#pragma once
#ifndef __HWINGRAPHICS_H__
#define __HWINGRAPHICS_H__

#include "hwindef.h"
#include "hwincom.h"
#include "hwinexception.h"


namespace harlinn
{
    namespace windows
    {
        class Control;

        namespace graphics
        {
#define HARLINN_WINDOWS_GRAPHICS_STANDARD_METHODS_IMPL( classType, baseClassType , interfaceType, baseInterfaceType ) \
public: \
typedef interfaceType InterfaceType; \
typedef baseInterfaceType BaseInterfaceType; \
private: \
 InterfaceType * GetInterface() const { HWIN_TRACE(); if(!unknown) { ThrowNoInterface(); } return reinterpret_cast< InterfaceType *>( unknown ); } \
public: \
classType () \
 : baseClassType ( ) \
 { HWIN_TRACE(); } \
explicit classType (interfaceType * theInterface, bool addref = false ) \
 : baseClassType ( reinterpret_cast< baseInterfaceType *>( theInterface ), addref ) \
 { HWIN_TRACE(); } \
protected: \
classType (REFIID iid, const Unknown& theUnknown, bool throwIfNoInterface = true ) \
 : baseClassType ( iid, reinterpret_cast< const baseClassType & > (theUnknown), throwIfNoInterface ) \
 { HWIN_TRACE(); } \
public: \
classType ( const Unknown& theUnknown, bool throwIfNoInterface = true ) \
 : baseClassType ( __uuidof(interfaceType), reinterpret_cast< const baseClassType & > (theUnknown),throwIfNoInterface ) \
 { HWIN_TRACE(); } \
classType (const classType & other) \
 : baseClassType ( reinterpret_cast< const baseClassType & > (other) ) \
 { HWIN_TRACE(); } \
classType (classType && other) \
 : baseClassType ( reinterpret_cast< baseClassType && >( other ) ) \
 { HWIN_TRACE(); } \
classType & operator = (const classType & other) \
 { \
   HWIN_TRACE(); \
   baseClassType :: operator = ( reinterpret_cast< const baseClassType & > (other) ); \
   return *this; \
 } \
classType & operator = (classType && other) \
 { \
   HWIN_TRACE(); \
   baseClassType :: operator = ( reinterpret_cast< baseClassType && > (other) ); \
   return *this; \
 } \
operator interfaceType * ( ) const\
 { \
   HWIN_TRACE(); \
   return reinterpret_cast< interfaceType * >( unknown ); \
 }




            class Factory;
            class BitmapRenderTarget;

            class Resource : public Unknown
            {
            public:
                typedef Unknown Base;

                HARLINN_WINDOWS_GRAPHICS_STANDARD_METHODS_IMPL(Resource,Unknown,ID2D1Resource,IUnknown)

            public:


                HWIN_EXPORT Factory GetFactory();
            };


            class Image : public Resource
            {
            public:
                typedef Resource Base;

                HARLINN_WINDOWS_GRAPHICS_STANDARD_METHODS_IMPL(Image, Resource,ID2D1Image,ID2D1Resource)

            };

            class Bitmap : public Image
            {
            public:
                typedef Image Base;

                HARLINN_WINDOWS_GRAPHICS_STANDARD_METHODS_IMPL(Bitmap, Image,ID2D1Bitmap,ID2D1Image)


                //
                // Returns the size of the bitmap in resolution independent units.
                //
                HWIN_EXPORT D2D1_SIZE_F GetSize( ) const;
    
    
                //
                // Returns the size of the bitmap in resolution dependent units, (pixels).
                //
                HWIN_EXPORT D2D1_SIZE_U GetPixelSize( ) const;
    
    
                //
                // Retrieve the format of the bitmap.
                //
                HWIN_EXPORT D2D1_PIXEL_FORMAT GetPixelFormat( ) const;
    
    
                //
                // Return the DPI of the bitmap.
                //
                HWIN_EXPORT const Bitmap& GetDpi(FLOAT *dpiX, FLOAT *dpiY ) const;

                const Bitmap& GetDpi(FLOAT& dpiX, FLOAT& dpiY ) const
                {
                    HWIN_TRACE();
                    return GetDpi(&dpiX, &dpiY);
                }

                D2D1_SIZE_F GetDpi( ) const
                {
                    HWIN_TRACE();
                    D2D1_SIZE_F result = {0,};
                    GetDpi(result.width,result.height);
                    return result;
                }
    
                HWIN_EXPORT Bitmap& CopyFromBitmap(const D2D1_POINT_2U *destPoint, ID2D1Bitmap *bitmap,const D2D1_RECT_U *srcRect );
    
                HWIN_EXPORT Bitmap& CopyFromRenderTarget(const D2D1_POINT_2U *destPoint, ID2D1RenderTarget *renderTarget,const D2D1_RECT_U *srcRect );
    
                HWIN_EXPORT Bitmap& CopyFromMemory(const D2D1_RECT_U *dstRect,const void *srcData,UINT32 pitch );

            };


            class GradientStopCollection : public Resource
            {
            public:
                typedef Resource Base;

                HARLINN_WINDOWS_GRAPHICS_STANDARD_METHODS_IMPL(GradientStopCollection, Resource,ID2D1GradientStopCollection,ID2D1Resource)


                //
                // Returns the number of stops in the gradient.
                //
                HWIN_EXPORT UINT32 GetGradientStopCount() const;
    
    
                //
                // Copies the gradient stops from the collection into the caller's interface.  The
                // returned colors have straight alpha.
                //
                HWIN_EXPORT const GradientStopCollection& GetGradientStops(D2D1_GRADIENT_STOP *gradientStops,UINT32 gradientStopsCount ) const;
    
    
                //
                // Returns whether the interpolation occurs with 1.0 or 2.2 gamma.
                //
                HWIN_EXPORT D2D1_GAMMA GetColorInterpolationGamma() const;
    
                HWIN_EXPORT D2D1_EXTEND_MODE GetExtendMode() const;

            };

            class Brush : public Resource
            {
            public:
                typedef Resource Base;

                HARLINN_WINDOWS_GRAPHICS_STANDARD_METHODS_IMPL(Brush, Resource,ID2D1Brush,ID2D1Resource)


                //
                // Sets the opacity for when the brush is drawn over the entire fill of the brush.
                //
                HWIN_EXPORT Brush& SetOpacity(FLOAT opacity );
    
    
                //
                // Sets the transform that applies to everything drawn by the brush.
                //
                HWIN_EXPORT Brush& SetTransform(const D2D1_MATRIX_3X2_F *transform );
    
                HWIN_EXPORT FLOAT GetOpacity() const;
    
                HWIN_EXPORT const Brush& GetTransform(D2D1_MATRIX_3X2_F *transform ) const;
    
                
                Brush& SetTransform(const D2D1_MATRIX_3X2_F &transform )  
                {
                    HWIN_TRACE();
                    SetTransform(&transform);
                }

            };

            class BitmapBrush : public Brush
            {
            public:
                typedef Brush Base;

                HARLINN_WINDOWS_GRAPHICS_STANDARD_METHODS_IMPL(BitmapBrush, Brush,ID2D1BitmapBrush,ID2D1Brush)

                //
                // Sets how the bitmap is to be treated outside of its natural extent on the X
                // axis.
                //
                HWIN_EXPORT BitmapBrush& SetExtendModeX(D2D1_EXTEND_MODE extendModeX );
    
    
                //
                // Sets how the bitmap is to be treated outside of its natural extent on the X
                // axis.
                //
                HWIN_EXPORT BitmapBrush& SetExtendModeY(D2D1_EXTEND_MODE extendModeY );
    
    
                //
                // Sets the interpolation mode used when this brush is used.
                //
                HWIN_EXPORT BitmapBrush& SetInterpolationMode(D2D1_BITMAP_INTERPOLATION_MODE interpolationMode );
    
    
                //
                // Sets the bitmap associated as the source of this brush.
                //
                HWIN_EXPORT BitmapBrush& SetBitmap(ID2D1Bitmap *bitmap );
    
                HWIN_EXPORT D2D1_EXTEND_MODE GetExtendModeX() const;
    
                HWIN_EXPORT D2D1_EXTEND_MODE GetExtendModeY() const;
    
                HWIN_EXPORT D2D1_BITMAP_INTERPOLATION_MODE GetInterpolationMode() const;
    
                HWIN_EXPORT Bitmap GetBitmap( ) const;

            };


            class SolidColorBrush : public Brush
            {
            public:
                typedef Brush Base;

                HARLINN_WINDOWS_GRAPHICS_STANDARD_METHODS_IMPL(SolidColorBrush, Brush,ID2D1SolidColorBrush,ID2D1Brush)

                HWIN_EXPORT SolidColorBrush& SetColor(const D2D1_COLOR_F *color );
    
                HWIN_EXPORT D2D1_COLOR_F GetColor() const;
    
                SolidColorBrush& SetColor(const D2D1_COLOR_F &color )  
                {
                    HWIN_TRACE();
                    return SetColor(&color);
                }
            };


            class LinearGradientBrush : public Brush
            {
            public:
                typedef Brush Base;

                HARLINN_WINDOWS_GRAPHICS_STANDARD_METHODS_IMPL(LinearGradientBrush, Brush,ID2D1LinearGradientBrush,ID2D1Brush)

                HWIN_EXPORT LinearGradientBrush& SetStartPoint(D2D1_POINT_2F startPoint );
    
    
                //
                // Sets the end point of the gradient in local coordinate space. This is not
                // influenced by the geometry being filled.
                //
                HWIN_EXPORT LinearGradientBrush& SetEndPoint(D2D1_POINT_2F endPoint );
    
                HWIN_EXPORT D2D1_POINT_2F GetStartPoint() const;
    
                HWIN_EXPORT D2D1_POINT_2F GetEndPoint() const;
    
                HWIN_EXPORT GradientStopCollection GetGradientStopCollection(  ) const;

            };


            class RadialGradientBrush : public Brush
            {
            public:
                typedef Brush Base;

                HARLINN_WINDOWS_GRAPHICS_STANDARD_METHODS_IMPL(RadialGradientBrush, Brush,ID2D1RadialGradientBrush,ID2D1Brush)

                //
                // Sets the center of the radial gradient. This will be in local coordinates and
                // will not depend on the geometry being filled.
                //
                HWIN_EXPORT RadialGradientBrush& SetCenter(D2D1_POINT_2F center );
    
    
                //
                // Sets offset of the origin relative to the radial gradient center.
                //
                HWIN_EXPORT RadialGradientBrush& SetGradientOriginOffset(D2D1_POINT_2F gradientOriginOffset );
    
                HWIN_EXPORT RadialGradientBrush& SetRadiusX(FLOAT radiusX );
    
                HWIN_EXPORT RadialGradientBrush& SetRadiusY(FLOAT radiusY );
    
                HWIN_EXPORT D2D1_POINT_2F GetCenter() const;
    
                HWIN_EXPORT D2D1_POINT_2F GetGradientOriginOffset() const;
    
                HWIN_EXPORT FLOAT GetRadiusX() const;
    
                HWIN_EXPORT FLOAT GetRadiusY() const;
    
                HWIN_EXPORT GradientStopCollection GetGradientStopCollection( ) const;

            };


            class StrokeStyle : public Resource
            {
            public:
                typedef Resource Base;

                HARLINN_WINDOWS_GRAPHICS_STANDARD_METHODS_IMPL(StrokeStyle, Resource,ID2D1StrokeStyle,ID2D1Resource)

                HWIN_EXPORT D2D1_CAP_STYLE GetStartCap() const;
    
                HWIN_EXPORT D2D1_CAP_STYLE GetEndCap() const;
    
                HWIN_EXPORT D2D1_CAP_STYLE GetDashCap() const;
    
                HWIN_EXPORT FLOAT GetMiterLimit() const;
    
                HWIN_EXPORT D2D1_LINE_JOIN GetLineJoin() const;
    
                HWIN_EXPORT FLOAT GetDashOffset() const;
    
                HWIN_EXPORT D2D1_DASH_STYLE GetDashStyle() const;
    
                HWIN_EXPORT UINT32 GetDashesCount() const;
    
    
                //
                // Returns the dashes from the object into a user allocated array. The user must
                // call GetDashesCount to retrieve the required size.
                //
                HWIN_EXPORT const StrokeStyle& GetDashes(FLOAT *dashes,UINT32 dashesCount ) const;

            };


            class Geometry : public Resource
            {
            public:
                typedef Resource Base;

                HARLINN_WINDOWS_GRAPHICS_STANDARD_METHODS_IMPL(Geometry, Resource,ID2D1Geometry,ID2D1Resource)


                //
                // Retrieve the bounds of the geometry, with an optional applied transform.
                //
                HWIN_EXPORT const Geometry& GetBounds(const D2D1_MATRIX_3X2_F *worldTransform, D2D1_RECT_F *bounds ) const;
    
    
                //
                // Get the bounds of the corresponding geometry after it has been widened or have
                // an optional pen style applied.
                //
                HWIN_EXPORT const Geometry& GetWidenedBounds(FLOAT strokeWidth,ID2D1StrokeStyle *strokeStyle,const D2D1_MATRIX_3X2_F *worldTransform,FLOAT flatteningTolerance,D2D1_RECT_F *bounds ) const;
    
    
                //
                // Checks to see whether the corresponding penned and widened geometry contains the
                // given point.
                //
                HWIN_EXPORT const Geometry& StrokeContainsPoint(D2D1_POINT_2F point,FLOAT strokeWidth,ID2D1StrokeStyle *strokeStyle,const D2D1_MATRIX_3X2_F *worldTransform,FLOAT flatteningTolerance,BOOL *contains ) const;
    
    
                //
                // Test whether the given fill of this geometry would contain this point.
                //
                HWIN_EXPORT const Geometry& FillContainsPoint(D2D1_POINT_2F point,const D2D1_MATRIX_3X2_F *worldTransform,FLOAT flatteningTolerance, BOOL *contains ) const;
    
    
                //
                // Compare how one geometry intersects or contains another geometry.
                //
                HWIN_EXPORT const Geometry& CompareWithGeometry(ID2D1Geometry *inputGeometry,const D2D1_MATRIX_3X2_F *inputGeometryTransform,FLOAT flatteningTolerance, D2D1_GEOMETRY_RELATION *relation ) const;
    
    
                //
                // Converts a geometry to a simplified geometry that has arcs and quadratic beziers
                // removed.
                //
                HWIN_EXPORT const Geometry& Simplify(D2D1_GEOMETRY_SIMPLIFICATION_OPTION simplificationOption,const D2D1_MATRIX_3X2_F *worldTransform,FLOAT flatteningTolerance, ID2D1SimplifiedGeometrySink *geometrySink ) const;
    
    
                //
                // Tessellates a geometry into triangles.
                //
                HWIN_EXPORT const Geometry& Tessellate(const D2D1_MATRIX_3X2_F *worldTransform,FLOAT flatteningTolerance, ID2D1TessellationSink *tessellationSink ) const;
    
    
                //
                // Performs a combine operation between the two geometries to produce a resulting
                // geometry.
                //
                HWIN_EXPORT const Geometry& CombineWithGeometry( ID2D1Geometry *inputGeometry,D2D1_COMBINE_MODE combineMode,const D2D1_MATRIX_3X2_F *inputGeometryTransform,FLOAT flatteningTolerance, ID2D1SimplifiedGeometrySink *geometrySink ) const;
    
    
                //
                // Computes the outline of the geometry. The result is written back into a
                // simplified geometry sink.
                //
                HWIN_EXPORT const Geometry& Outline(const D2D1_MATRIX_3X2_F *worldTransform,FLOAT flatteningTolerance, ID2D1SimplifiedGeometrySink *geometrySink ) const;
    
    
                //
                // Computes the area of the geometry.
                //
                HWIN_EXPORT const Geometry& ComputeArea(const D2D1_MATRIX_3X2_F *worldTransform,FLOAT flatteningTolerance, FLOAT *area ) const;
    
    
                //
                // Computes the length of the geometry.
                //
                HWIN_EXPORT const Geometry& ComputeLength(const D2D1_MATRIX_3X2_F *worldTransform,FLOAT flatteningTolerance, FLOAT *length ) const;
    
    
                //
                // Computes the point and tangent a given distance along the path.
                //
                HWIN_EXPORT const Geometry& ComputePointAtLength(FLOAT length,const D2D1_MATRIX_3X2_F *worldTransform,FLOAT flatteningTolerance, D2D1_POINT_2F *point, D2D1_POINT_2F *unitTangentVector ) const;
    
    
                //
                // Get the geometry and widen it as well as apply an optional pen style.
                //
                HWIN_EXPORT const Geometry& Widen(FLOAT strokeWidth,ID2D1StrokeStyle *strokeStyle,const D2D1_MATRIX_3X2_F *worldTransform,FLOAT flatteningTolerance, ID2D1SimplifiedGeometrySink *geometrySink ) const;
    
    
                //
                // Retrieve the bounds of the geometry, with an optional applied transform.
                //
                
                const Geometry& GetBounds(const D2D1_MATRIX_3X2_F &worldTransform, D2D1_RECT_F *bounds ) const  
                {
                    HWIN_TRACE();
                    return GetBounds(&worldTransform, bounds);
                }
    
    
                //
                // Get the bounds of the corresponding geometry after it has been widened or have
                // an optional pen style applied.
                //
                
                const Geometry& GetWidenedBounds(FLOAT strokeWidth,ID2D1StrokeStyle *strokeStyle, const D2D1_MATRIX_3X2_F &worldTransform, FLOAT flatteningTolerance, D2D1_RECT_F *bounds ) const
                {
                    HWIN_TRACE();
                    return GetWidenedBounds(strokeWidth, strokeStyle, &worldTransform, flatteningTolerance, bounds);
                }
    
    
                //
                // Get the bounds of the corresponding geometry after it has been widened or have
                // an optional pen style applied.
                //
                
                const Geometry& GetWidenedBounds(FLOAT strokeWidth,ID2D1StrokeStyle *strokeStyle,const D2D1_MATRIX_3X2_F *worldTransform,D2D1_RECT_F *bounds ) const  
                {
                    HWIN_TRACE();
                    return GetWidenedBounds(strokeWidth, strokeStyle, worldTransform, D2D1_DEFAULT_FLATTENING_TOLERANCE, bounds);
                }
    
    
                //
                // Get the bounds of the corresponding geometry after it has been widened or have
                // an optional pen style applied.
                //
                
                const Geometry& GetWidenedBounds(FLOAT strokeWidth,ID2D1StrokeStyle *strokeStyle,const D2D1_MATRIX_3X2_F &worldTransform,D2D1_RECT_F *bounds) const  
                {
                    HWIN_TRACE();
                    return GetWidenedBounds(strokeWidth, strokeStyle, &worldTransform, D2D1_DEFAULT_FLATTENING_TOLERANCE, bounds);
                }
    
                
                const Geometry& StrokeContainsPoint(D2D1_POINT_2F point, FLOAT strokeWidth, ID2D1StrokeStyle *strokeStyle, const D2D1_MATRIX_3X2_F &worldTransform, FLOAT flatteningTolerance, BOOL *contains ) const  
                {
                    HWIN_TRACE();
                    return StrokeContainsPoint(point, strokeWidth, strokeStyle, &worldTransform, flatteningTolerance, contains);
                }
    
    
                //
                // Checks to see whether the corresponding penned and widened geometry contains the
                // given point.
                //
                const Geometry& StrokeContainsPoint(D2D1_POINT_2F point, FLOAT strokeWidth, ID2D1StrokeStyle *strokeStyle, const D2D1_MATRIX_3X2_F *worldTransform, BOOL *contains ) const  
                {
                    HWIN_TRACE();
                    return StrokeContainsPoint(point, strokeWidth, strokeStyle, worldTransform, D2D1_DEFAULT_FLATTENING_TOLERANCE, contains);
                }
    
                
                const Geometry& StrokeContainsPoint( D2D1_POINT_2F point, FLOAT strokeWidth, ID2D1StrokeStyle *strokeStyle, const D2D1_MATRIX_3X2_F &worldTransform, BOOL *contains ) const  
                {
                    HWIN_TRACE();
                    return StrokeContainsPoint(point, strokeWidth, strokeStyle, &worldTransform, D2D1_DEFAULT_FLATTENING_TOLERANCE, contains);
                }
    
                const Geometry& FillContainsPoint( D2D1_POINT_2F point, const D2D1_MATRIX_3X2_F &worldTransform, FLOAT flatteningTolerance, BOOL *contains ) const  
                {
                    HWIN_TRACE();
                    return FillContainsPoint(point, &worldTransform, flatteningTolerance, contains);
                }
    
    
                //
                // Test whether the given fill of this geometry would contain this point.
                //
                const Geometry& FillContainsPoint(D2D1_POINT_2F point,const D2D1_MATRIX_3X2_F *worldTransform, BOOL *contains ) const  
                {
                    HWIN_TRACE();
                    return FillContainsPoint(point, worldTransform, D2D1_DEFAULT_FLATTENING_TOLERANCE, contains);
                }
    
                const Geometry& FillContainsPoint( D2D1_POINT_2F point, const D2D1_MATRIX_3X2_F &worldTransform, BOOL *contains ) const  
                {
                    HWIN_TRACE();
                    return FillContainsPoint(point, &worldTransform, D2D1_DEFAULT_FLATTENING_TOLERANCE, contains);
                }
    
    
                //
                // Compare how one geometry intersects or contains another geometry.
                //
                
                const Geometry& CompareWithGeometry(ID2D1Geometry *inputGeometry, const D2D1_MATRIX_3X2_F &inputGeometryTransform, FLOAT flatteningTolerance, D2D1_GEOMETRY_RELATION *relation) const  
                {
                    HWIN_TRACE();
                    return CompareWithGeometry(inputGeometry, &inputGeometryTransform, flatteningTolerance, relation);
                }
    
    
                //
                // Compare how one geometry intersects or contains another geometry.
                //
                
                const Geometry& CompareWithGeometry( ID2D1Geometry *inputGeometry,const D2D1_MATRIX_3X2_F *inputGeometryTransform, D2D1_GEOMETRY_RELATION *relation ) const  
                {
                    HWIN_TRACE();
                    return CompareWithGeometry(inputGeometry, inputGeometryTransform, D2D1_DEFAULT_FLATTENING_TOLERANCE, relation);
                }
    
    
                //
                // Compare how one geometry intersects or contains another geometry.
                //
                const Geometry& CompareWithGeometry(ID2D1Geometry *inputGeometry, const D2D1_MATRIX_3X2_F &inputGeometryTransform, D2D1_GEOMETRY_RELATION *relation ) const  
                {
                    HWIN_TRACE();
                    return CompareWithGeometry(inputGeometry, &inputGeometryTransform, D2D1_DEFAULT_FLATTENING_TOLERANCE, relation);
                }
    
    
                //
                // Converts a geometry to a simplified geometry that has arcs and quadratic beziers
                // removed.
                //
                const Geometry& Simplify( D2D1_GEOMETRY_SIMPLIFICATION_OPTION simplificationOption, const D2D1_MATRIX_3X2_F &worldTransform, FLOAT flatteningTolerance, ID2D1SimplifiedGeometrySink *geometrySink ) const  
                {
                    HWIN_TRACE();
                    return Simplify(simplificationOption, &worldTransform, flatteningTolerance, geometrySink);
                }
    
    
                //
                // Converts a geometry to a simplified geometry that has arcs and quadratic beziers
                // removed.
                //
                
                const Geometry& Simplify(D2D1_GEOMETRY_SIMPLIFICATION_OPTION simplificationOption, const D2D1_MATRIX_3X2_F *worldTransform, ID2D1SimplifiedGeometrySink *geometrySink ) const  
                {
                    HWIN_TRACE();
                    return Simplify(simplificationOption, worldTransform, D2D1_DEFAULT_FLATTENING_TOLERANCE, geometrySink);
                }
    
    
                //
                // Converts a geometry to a simplified geometry that has arcs and quadratic beziers
                // removed.
                //
                const Geometry& Simplify( D2D1_GEOMETRY_SIMPLIFICATION_OPTION simplificationOption, const D2D1_MATRIX_3X2_F &worldTransform, ID2D1SimplifiedGeometrySink *geometrySink ) const  
                {
                    HWIN_TRACE();
                    return Simplify(simplificationOption, &worldTransform, D2D1_DEFAULT_FLATTENING_TOLERANCE, geometrySink);
                }
    
    
                //
                // Tessellates a geometry into triangles.
                //
                
                const Geometry& Tessellate(const D2D1_MATRIX_3X2_F &worldTransform, FLOAT flatteningTolerance, ID2D1TessellationSink *tessellationSink ) const  
                {
                    HWIN_TRACE();
                    return Tessellate(&worldTransform, flatteningTolerance, tessellationSink);
                }
    
    
                //
                // Tessellates a geometry into triangles.
                //
                
                const Geometry& Tessellate(const D2D1_MATRIX_3X2_F *worldTransform, ID2D1TessellationSink *tessellationSink ) const  
                {
                    HWIN_TRACE();
                    return Tessellate(worldTransform, D2D1_DEFAULT_FLATTENING_TOLERANCE, tessellationSink);
                }
    
    
                //
                // Tessellates a geometry into triangles.
                //
                
                const Geometry& Tessellate(const D2D1_MATRIX_3X2_F &worldTransform, ID2D1TessellationSink *tessellationSink) const  
                {
                    HWIN_TRACE();
                    return Tessellate(&worldTransform, D2D1_DEFAULT_FLATTENING_TOLERANCE, tessellationSink);
                }
    
    
                //
                // Performs a combine operation between the two geometries to produce a resulting
                // geometry.
                //
                const Geometry& CombineWithGeometry( ID2D1Geometry *inputGeometry, D2D1_COMBINE_MODE combineMode, const D2D1_MATRIX_3X2_F &inputGeometryTransform, FLOAT flatteningTolerance, ID2D1SimplifiedGeometrySink *geometrySink ) const  
                {
                    HWIN_TRACE();
                    return CombineWithGeometry(inputGeometry, combineMode, &inputGeometryTransform, flatteningTolerance, geometrySink);
                }
    
    
                //
                // Performs a combine operation between the two geometries to produce a resulting
                // geometry.
                //
                const Geometry& CombineWithGeometry( ID2D1Geometry *inputGeometry, D2D1_COMBINE_MODE combineMode, const D2D1_MATRIX_3X2_F *inputGeometryTransform, ID2D1SimplifiedGeometrySink *geometrySink ) const  
                {
                    HWIN_TRACE();
                    return CombineWithGeometry(inputGeometry, combineMode, inputGeometryTransform, D2D1_DEFAULT_FLATTENING_TOLERANCE, geometrySink);
                }
    
    
                //
                // Performs a combine operation between the two geometries to produce a resulting
                // geometry.
                //
                
                const Geometry& CombineWithGeometry(ID2D1Geometry *inputGeometry, D2D1_COMBINE_MODE combineMode, const D2D1_MATRIX_3X2_F &inputGeometryTransform, ID2D1SimplifiedGeometrySink *geometrySink ) const  
                {
                    HWIN_TRACE();
                    return CombineWithGeometry(inputGeometry, combineMode, &inputGeometryTransform, D2D1_DEFAULT_FLATTENING_TOLERANCE, geometrySink);
                }
    
    
                //
                // Computes the outline of the geometry. The result is written back into a
                // simplified geometry sink.
                //
                
                const Geometry& Outline(const D2D1_MATRIX_3X2_F &worldTransform,FLOAT flatteningTolerance, ID2D1SimplifiedGeometrySink *geometrySink ) const  
                {
                    HWIN_TRACE();
                    return Outline(&worldTransform, flatteningTolerance, geometrySink);
                }
    
    
                //
                // Computes the outline of the geometry. The result is written back into a
                // simplified geometry sink.
                //
                
                const Geometry& Outline(const D2D1_MATRIX_3X2_F *worldTransform, ID2D1SimplifiedGeometrySink *geometrySink ) const  
                {
                    HWIN_TRACE();
                    return Outline(worldTransform, D2D1_DEFAULT_FLATTENING_TOLERANCE, geometrySink);
                }
    
    
                //
                // Computes the outline of the geometry. The result is written back into a
                // simplified geometry sink.
                //
                
                const Geometry& Outline(const D2D1_MATRIX_3X2_F &worldTransform, ID2D1SimplifiedGeometrySink *geometrySink ) const  
                {
                    HWIN_TRACE();
                    return Outline(&worldTransform, D2D1_DEFAULT_FLATTENING_TOLERANCE, geometrySink);
                }
    
    
                //
                // Computes the area of the geometry.
                //
                
                const Geometry& ComputeArea(const D2D1_MATRIX_3X2_F &worldTransform,FLOAT flatteningTolerance,FLOAT *area ) const  
                {
                    HWIN_TRACE();
                    return ComputeArea(&worldTransform, flatteningTolerance, area);
                }
    
    
                //
                // Computes the area of the geometry.
                //
                
                const Geometry& ComputeArea( const D2D1_MATRIX_3X2_F *worldTransform, FLOAT *area ) const  
                {
                    HWIN_TRACE();
                    return ComputeArea(worldTransform, D2D1_DEFAULT_FLATTENING_TOLERANCE, area);
                }
    
    
                //
                // Computes the area of the geometry.
                //
                const Geometry& ComputeArea( const D2D1_MATRIX_3X2_F &worldTransform, FLOAT *area ) const  
                {
                    HWIN_TRACE();
                    return ComputeArea(&worldTransform, D2D1_DEFAULT_FLATTENING_TOLERANCE, area);
                }
    
    
                //
                // Computes the length of the geometry.
                //
                
                const Geometry& ComputeLength(const D2D1_MATRIX_3X2_F &worldTransform,FLOAT flatteningTolerance, FLOAT *length) const  
                {
                    HWIN_TRACE();
                    return ComputeLength(&worldTransform, flatteningTolerance, length);
                }
    
    
                //
                // Computes the length of the geometry.
                //
                
                const Geometry& ComputeLength(const D2D1_MATRIX_3X2_F *worldTransform,FLOAT *length ) const  
                {
                    HWIN_TRACE();
                    return ComputeLength(worldTransform, D2D1_DEFAULT_FLATTENING_TOLERANCE, length);
                }
    
    
                //
                // Computes the length of the geometry.
                //
                
                const Geometry& ComputeLength(const D2D1_MATRIX_3X2_F &worldTransform, FLOAT *length ) const  
                {
                    HWIN_TRACE();
                    return ComputeLength(&worldTransform, D2D1_DEFAULT_FLATTENING_TOLERANCE, length);
                }
    
    
                //
                // Computes the point and tangent a given distance along the path.
                //
                
                const Geometry& ComputePointAtLength(FLOAT length, const D2D1_MATRIX_3X2_F &worldTransform, FLOAT flatteningTolerance, D2D1_POINT_2F *point, D2D1_POINT_2F *unitTangentVector) const  
                {
                    HWIN_TRACE();
                    return ComputePointAtLength(length, &worldTransform, flatteningTolerance, point, unitTangentVector);
                }
    
    
                //
                // Computes the point and tangent a given distance along the path.
                //
                
                const Geometry& ComputePointAtLength( FLOAT length, const D2D1_MATRIX_3X2_F *worldTransform, D2D1_POINT_2F *point, D2D1_POINT_2F *unitTangentVector ) const  
                {
                    HWIN_TRACE();
                    return ComputePointAtLength(length, worldTransform, D2D1_DEFAULT_FLATTENING_TOLERANCE, point, unitTangentVector);
                }
    
    
                //
                // Computes the point and tangent a given distance along the path.
                //
                
                const Geometry& ComputePointAtLength(FLOAT length, const D2D1_MATRIX_3X2_F &worldTransform, D2D1_POINT_2F *point, D2D1_POINT_2F *unitTangentVector ) const  
                {
                    HWIN_TRACE();
                    return ComputePointAtLength(length, &worldTransform, D2D1_DEFAULT_FLATTENING_TOLERANCE, point, unitTangentVector);
                }
    
    
                //
                // Get the geometry and widen it as well as apply an optional pen style.
                //
                
                const Geometry& Widen(FLOAT strokeWidth, ID2D1StrokeStyle *strokeStyle,const D2D1_MATRIX_3X2_F &worldTransform, FLOAT flatteningTolerance, ID2D1SimplifiedGeometrySink *geometrySink ) const  
                {
                    HWIN_TRACE();
                    return Widen(strokeWidth, strokeStyle, &worldTransform, flatteningTolerance, geometrySink);
                }
    
    
                //
                // Get the geometry and widen it as well as apply an optional pen style.
                //
                
                const Geometry& Widen(FLOAT strokeWidth, ID2D1StrokeStyle *strokeStyle, const D2D1_MATRIX_3X2_F *worldTransform, ID2D1SimplifiedGeometrySink *geometrySink) const  
                {
                    HWIN_TRACE();
                    return Widen(strokeWidth, strokeStyle, worldTransform, D2D1_DEFAULT_FLATTENING_TOLERANCE, geometrySink);
                }
    
    
                //
                // Get the geometry and widen it as well as apply an optional pen style.
                //
                
                const Geometry& Widen(FLOAT strokeWidth, ID2D1StrokeStyle *strokeStyle, const D2D1_MATRIX_3X2_F &worldTransform, ID2D1SimplifiedGeometrySink *geometrySink) const  
                {
                    HWIN_TRACE();
                    return Widen(strokeWidth, strokeStyle, &worldTransform, D2D1_DEFAULT_FLATTENING_TOLERANCE, geometrySink);
                }

            };

            class RectangleGeometry : public Geometry
            {
            public:
                typedef Geometry Base;

                HARLINN_WINDOWS_GRAPHICS_STANDARD_METHODS_IMPL(RectangleGeometry, Geometry,ID2D1RectangleGeometry,ID2D1Geometry)

                HWIN_EXPORT const RectangleGeometry& GetRect( D2D1_RECT_F *rect ) const;

                const RectangleGeometry& GetRect( D2D1_RECT_F& rect ) const
                {
                    HWIN_TRACE();
                    return GetRect(&rect);
                }


                const D2D1_RECT_F GetRect( ) const
                {
                    HWIN_TRACE();
                    D2D1_RECT_F result = {0,};
                    GetRect(&result);
                    return result;
                }

            };

            class RoundedRectangleGeometry : public Geometry
            {
            public:
                typedef Geometry Base;

                HARLINN_WINDOWS_GRAPHICS_STANDARD_METHODS_IMPL(RoundedRectangleGeometry, Geometry,ID2D1RoundedRectangleGeometry,ID2D1Geometry)


                HWIN_EXPORT const RoundedRectangleGeometry& GetRoundedRect(D2D1_ROUNDED_RECT *roundedRect ) const;

                const RoundedRectangleGeometry& GetRoundedRect(D2D1_ROUNDED_RECT& roundedRect ) const
                {
                    HWIN_TRACE();
                    return GetRoundedRect(&roundedRect);
                }

                const D2D1_ROUNDED_RECT GetRoundedRect( ) const
                {
                    HWIN_TRACE();
                    D2D1_ROUNDED_RECT result = {0,};
                    GetRoundedRect(&result);
                    return result;
                }


            };

            class EllipseGeometry : public Geometry
            {
            public:
                typedef Geometry Base;

                HARLINN_WINDOWS_GRAPHICS_STANDARD_METHODS_IMPL(EllipseGeometry, Geometry,ID2D1EllipseGeometry,ID2D1Geometry)


                HWIN_EXPORT const EllipseGeometry& GetEllipse(D2D1_ELLIPSE *ellipse ) const;


                const EllipseGeometry& GetEllipse(D2D1_ELLIPSE& ellipse ) const
                {
                    HWIN_TRACE();
                    return GetEllipse(&ellipse);
                }

                D2D1_ELLIPSE GetEllipse( ) const
                {
                    HWIN_TRACE();
                    D2D1_ELLIPSE result = {0,};
                    GetEllipse(&result);
                    return result;
                }


            };


            class GeometryGroup : public Geometry
            {
            public:
                typedef Geometry Base;

                HARLINN_WINDOWS_GRAPHICS_STANDARD_METHODS_IMPL(GeometryGroup, Geometry,ID2D1GeometryGroup,ID2D1Geometry)

                HWIN_EXPORT D2D1_FILL_MODE GetFillMode() const;
    
                HWIN_EXPORT UINT32 GetSourceGeometryCount( ) const;
    
                HWIN_EXPORT const GeometryGroup& GetSourceGeometries( ID2D1Geometry **geometries, UINT32 geometriesCount ) const;

            };


            class TransformedGeometry : public Geometry
            {
            public:
                typedef Geometry Base;

                HARLINN_WINDOWS_GRAPHICS_STANDARD_METHODS_IMPL(TransformedGeometry, Geometry,ID2D1TransformedGeometry,ID2D1Geometry)


                HWIN_EXPORT const TransformedGeometry& GetSourceGeometry( ID2D1Geometry **sourceGeometry ) const;
    
                HWIN_EXPORT const TransformedGeometry& GetTransform( D2D1_MATRIX_3X2_F *transform ) const;

            };


            class SimplifiedGeometrySink : public Unknown
            {
            public:
                typedef Unknown Base;

                HARLINN_WINDOWS_GRAPHICS_STANDARD_METHODS_IMPL(SimplifiedGeometrySink,Unknown,ID2D1SimplifiedGeometrySink,IUnknown)


                HWIN_EXPORT SimplifiedGeometrySink& SetFillMode(D2D1_FILL_MODE fillMode );
    
                HWIN_EXPORT SimplifiedGeometrySink& SetSegmentFlags(D2D1_PATH_SEGMENT vertexFlags );
    
                HWIN_EXPORT SimplifiedGeometrySink& BeginFigure(D2D1_POINT_2F startPoint,D2D1_FIGURE_BEGIN figureBegin );
    
                HWIN_EXPORT SimplifiedGeometrySink& AddLines(const D2D1_POINT_2F *points,UINT32 pointsCount );
    
                HWIN_EXPORT SimplifiedGeometrySink& AddBeziers(const D2D1_BEZIER_SEGMENT *beziers,UINT32 beziersCount );
    
                HWIN_EXPORT SimplifiedGeometrySink& EndFigure(D2D1_FIGURE_END figureEnd );
    
                HWIN_EXPORT SimplifiedGeometrySink& Close();
            };


            class GeometrySink : public SimplifiedGeometrySink
            {
            public:
                typedef SimplifiedGeometrySink Base;

                HARLINN_WINDOWS_GRAPHICS_STANDARD_METHODS_IMPL(GeometrySink,SimplifiedGeometrySink,ID2D1GeometrySink,ID2D1SimplifiedGeometrySink)


                HWIN_EXPORT GeometrySink& AddLine(D2D1_POINT_2F point);
    
                HWIN_EXPORT GeometrySink& AddBezier(const D2D1_BEZIER_SEGMENT *bezier);
    
                HWIN_EXPORT GeometrySink& AddQuadraticBezier(const D2D1_QUADRATIC_BEZIER_SEGMENT *bezier );
    
                HWIN_EXPORT GeometrySink& AddQuadraticBeziers(const D2D1_QUADRATIC_BEZIER_SEGMENT *beziers,UINT32 beziersCount );
    
                HWIN_EXPORT GeometrySink& AddArc(const D2D1_ARC_SEGMENT *arc );
    
                GeometrySink& AddBezier(const D2D1_BEZIER_SEGMENT &bezier)  
                {
                    HWIN_TRACE();
                    return AddBezier(&bezier);
                }
    
                GeometrySink& AddQuadraticBezier(const D2D1_QUADRATIC_BEZIER_SEGMENT &bezier )  
                {
                    HWIN_TRACE();
                    return AddQuadraticBezier(&bezier);
                }
    
                GeometrySink& AddArc( const D2D1_ARC_SEGMENT &arc )  
                {
                    HWIN_TRACE();
                    return AddArc(&arc);
                }

            };


            class TessellationSink : public Unknown
            {
            public:
                typedef Unknown Base;

                HARLINN_WINDOWS_GRAPHICS_STANDARD_METHODS_IMPL(TessellationSink,Unknown,ID2D1TessellationSink,IUnknown)

                HWIN_EXPORT TessellationSink& AddTriangles(const D2D1_TRIANGLE *triangles, UINT32 trianglesCount );
    
                HWIN_EXPORT TessellationSink& Close();

            };


            class PathGeometry : public Geometry
            {
            public:
                typedef Geometry Base;

                HARLINN_WINDOWS_GRAPHICS_STANDARD_METHODS_IMPL(PathGeometry, Geometry,ID2D1PathGeometry,ID2D1Geometry)

                //
                // Opens a geometry sink that will be used to create this path geometry.
                //
                HWIN_EXPORT PathGeometry& Open(ID2D1GeometrySink **geometrySink);

                HWIN_EXPORT GeometrySink Open( );
    
    
                //
                // Retrieve the contents of this geometry. The caller passes an implementation of a
                // ID2D1GeometrySink interface to receive the data.
                //
                HWIN_EXPORT const PathGeometry& Stream(ID2D1GeometrySink *geometrySink) const;
    
                HWIN_EXPORT const PathGeometry& GetSegmentCount(UINT32 *count) const;
                HWIN_EXPORT UINT32 GetSegmentCount( ) const;
    
                HWIN_EXPORT const PathGeometry& GetFigureCount(UINT32 *count) const;
                HWIN_EXPORT UINT32 GetFigureCount( ) const;
            };

            class Mesh : public Resource
            {
            public:
                typedef Resource Base;

                HARLINN_WINDOWS_GRAPHICS_STANDARD_METHODS_IMPL(Mesh, Resource,ID2D1Mesh,ID2D1Resource)


                //
                // Opens the mesh for population.
                //
                HWIN_EXPORT Mesh& Open(ID2D1TessellationSink **tessellationSink );
                HWIN_EXPORT TessellationSink Open( );

            };

            class Layer : public Resource
            {
            public:
                typedef Resource Base;

                HARLINN_WINDOWS_GRAPHICS_STANDARD_METHODS_IMPL(Layer, Resource,ID2D1Layer,ID2D1Resource)

                HWIN_EXPORT D2D1_SIZE_F GetSize() const;

            };

            class DrawingStateBlock : public Resource
            {
            public:
                typedef Resource Base;

                HARLINN_WINDOWS_GRAPHICS_STANDARD_METHODS_IMPL(DrawingStateBlock, Resource,ID2D1DrawingStateBlock,ID2D1Resource)

                //
                // Retrieves the state currently contained within this state block resource.
                //
                HWIN_EXPORT const DrawingStateBlock& GetDescription(D2D1_DRAWING_STATE_DESCRIPTION *stateDescription ) const;
    
    
                //
                // Sets the state description of this state block resource.
                //
                HWIN_EXPORT DrawingStateBlock& SetDescription(const D2D1_DRAWING_STATE_DESCRIPTION *stateDescription );
    
    
                //
                // Sets the text rendering parameters of this state block resource.
                //
                HWIN_EXPORT DrawingStateBlock& SetTextRenderingParams(IDWriteRenderingParams *textRenderingParams = NULL );
    
    
                //
                // Retrieves the text rendering parameters contained within this state block
                // resource. If a NULL text rendering parameter was specified, NULL will be
                // returned.
                //
                HWIN_EXPORT const DrawingStateBlock& GetTextRenderingParams(IDWriteRenderingParams **textRenderingParams ) const;
    
                DrawingStateBlock& SetDescription(CONST D2D1_DRAWING_STATE_DESCRIPTION &stateDescription )  
                {
                    HWIN_TRACE();
                    SetDescription(&stateDescription);
                }


            };


            class RenderTarget : public Resource
            {
            public:
                typedef Resource Base;
            public:
                HARLINN_WINDOWS_GRAPHICS_STANDARD_METHODS_IMPL(RenderTarget, Resource,ID2D1RenderTarget,ID2D1Resource)

                //
                // Create a D2D bitmap by copying from memory, or create uninitialized.
                //
                HWIN_EXPORT Bitmap CreateBitmap(D2D1_SIZE_U size, const void *srcData, UINT32 pitch, const D2D1_BITMAP_PROPERTIES* bitmapProperties);
                HWIN_EXPORT Bitmap CreateBitmap(D2D1_SIZE_U size, const void *srcData, UINT32 pitch, const D2D1_BITMAP_PROPERTIES& bitmapProperties);

                HWIN_EXPORT Bitmap CreateBitmap(D2D1_SIZE_U size, const D2D1_BITMAP_PROPERTIES* bitmapProperties);
                HWIN_EXPORT Bitmap CreateBitmap(D2D1_SIZE_U size, const D2D1_BITMAP_PROPERTIES& bitmapProperties);
    
    
                //
                // Create a D2D bitmap by copying a WIC bitmap.
                //
                HWIN_EXPORT Bitmap CreateBitmapFromWicBitmap(IWICBitmapSource *wicBitmapSource,const D2D1_BITMAP_PROPERTIES* bitmapProperties);
                HWIN_EXPORT Bitmap CreateBitmapFromWicBitmap(IWICBitmapSource *wicBitmapSource,const D2D1_BITMAP_PROPERTIES& bitmapProperties);
                HWIN_EXPORT Bitmap CreateBitmapFromWicBitmap(IWICBitmapSource *wicBitmapSource );
    
    
                //
                // Create a D2D bitmap by sharing bits from another resource. The bitmap must be
                // compatible with the render target for the call to succeed.
                // For example, an IWICBitmap can be shared with a software target, or a DXGI
                // surface can be shared with a DXGI render target.
                //
                HWIN_EXPORT Bitmap CreateSharedBitmap(REFIID riid,void *data,const D2D1_BITMAP_PROPERTIES* bitmapProperties);
                HWIN_EXPORT Bitmap CreateSharedBitmap(REFIID riid,void *data,const D2D1_BITMAP_PROPERTIES& bitmapProperties);
    
    
                //
                // Creates a bitmap brush. The bitmap is scaled, rotated, skewed or tiled to fill
                // or pen a geometry.
                //
                HWIN_EXPORT BitmapBrush CreateBitmapBrush(ID2D1Bitmap *bitmap,const D2D1_BITMAP_BRUSH_PROPERTIES* bitmapBrushProperties,const D2D1_BRUSH_PROPERTIES* brushProperties);
                HWIN_EXPORT BitmapBrush CreateBitmapBrush(ID2D1Bitmap *bitmap,const D2D1_BITMAP_BRUSH_PROPERTIES& bitmapBrushProperties,const D2D1_BRUSH_PROPERTIES* brushProperties);
                HWIN_EXPORT BitmapBrush CreateBitmapBrush(ID2D1Bitmap *bitmap,const D2D1_BITMAP_BRUSH_PROPERTIES* bitmapBrushProperties,const D2D1_BRUSH_PROPERTIES& brushProperties);
                HWIN_EXPORT BitmapBrush CreateBitmapBrush(ID2D1Bitmap *bitmap,const D2D1_BITMAP_BRUSH_PROPERTIES& bitmapBrushProperties,const D2D1_BRUSH_PROPERTIES& brushProperties);
                HWIN_EXPORT BitmapBrush CreateBitmapBrush(ID2D1Bitmap *bitmap,const D2D1_BRUSH_PROPERTIES* brushProperties);
                HWIN_EXPORT BitmapBrush CreateBitmapBrush(ID2D1Bitmap *bitmap,const D2D1_BRUSH_PROPERTIES& brushProperties);
                HWIN_EXPORT BitmapBrush CreateBitmapBrush(ID2D1Bitmap *bitmap,const D2D1_BITMAP_BRUSH_PROPERTIES* bitmapBrushProperties);
                HWIN_EXPORT BitmapBrush CreateBitmapBrush(ID2D1Bitmap *bitmap,const D2D1_BITMAP_BRUSH_PROPERTIES& bitmapBrushProperties);
                HWIN_EXPORT BitmapBrush CreateBitmapBrush(ID2D1Bitmap *bitmap );
    


                HWIN_EXPORT SolidColorBrush CreateSolidColorBrush(const D2D1_COLOR_F* color,const D2D1_BRUSH_PROPERTIES* brushProperties);
                HWIN_EXPORT SolidColorBrush CreateSolidColorBrush(const D2D1_COLOR_F& color,const D2D1_BRUSH_PROPERTIES* brushProperties);
                HWIN_EXPORT SolidColorBrush CreateSolidColorBrush(const D2D1_COLOR_F* color,const D2D1_BRUSH_PROPERTIES& brushProperties);
                HWIN_EXPORT SolidColorBrush CreateSolidColorBrush(const D2D1_COLOR_F& color,const D2D1_BRUSH_PROPERTIES& brushProperties);
                HWIN_EXPORT SolidColorBrush CreateSolidColorBrush(const D2D1_COLOR_F* color);
                HWIN_EXPORT SolidColorBrush CreateSolidColorBrush(const D2D1_COLOR_F& color);
    
    
                //
                // A gradient stop collection represents a set of stops in an ideal unit length.
                // This is the source resource for a linear gradient and radial gradient brush.
                //
                HWIN_EXPORT GradientStopCollection CreateGradientStopCollection(const D2D1_GRADIENT_STOP *gradientStops,
                    UINT32 gradientStopsCount,
                    D2D1_GAMMA colorInterpolationGamma, // Specifies which space the color interpolation occurs in.
                    D2D1_EXTEND_MODE extendMode); // Specifies how the gradient will be extended outside of the unit length.

                HWIN_EXPORT GradientStopCollection CreateGradientStopCollection(const D2D1_GRADIENT_STOP *gradientStops, UINT32 gradientStopsCount);
    


                HWIN_EXPORT LinearGradientBrush CreateLinearGradientBrush(const D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES* linearGradientBrushProperties, const D2D1_BRUSH_PROPERTIES* brushProperties, ID2D1GradientStopCollection* gradientStopCollection);
                HWIN_EXPORT LinearGradientBrush CreateLinearGradientBrush(const D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES& linearGradientBrushProperties, const D2D1_BRUSH_PROPERTIES* brushProperties, ID2D1GradientStopCollection* gradientStopCollection);
                HWIN_EXPORT LinearGradientBrush CreateLinearGradientBrush(const D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES* linearGradientBrushProperties, const D2D1_BRUSH_PROPERTIES& brushProperties, ID2D1GradientStopCollection* gradientStopCollection);
                HWIN_EXPORT LinearGradientBrush CreateLinearGradientBrush(const D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES& linearGradientBrushProperties, const D2D1_BRUSH_PROPERTIES& brushProperties, ID2D1GradientStopCollection* gradientStopCollection);

                HWIN_EXPORT LinearGradientBrush CreateLinearGradientBrush(const D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES* linearGradientBrushProperties, ID2D1GradientStopCollection* gradientStopCollection);
                HWIN_EXPORT LinearGradientBrush CreateLinearGradientBrush(const D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES& linearGradientBrushProperties, ID2D1GradientStopCollection* gradientStopCollection);
                HWIN_EXPORT LinearGradientBrush CreateLinearGradientBrush(const D2D1_POINT_2F& startPoint, const D2D1_POINT_2F& endPoint, ID2D1GradientStopCollection* gradientStopCollection);



    
                HWIN_EXPORT RadialGradientBrush CreateRadialGradientBrush(const D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES* radialGradientBrushProperties, const D2D1_BRUSH_PROPERTIES* brushProperties, ID2D1GradientStopCollection* gradientStopCollection);
                HWIN_EXPORT RadialGradientBrush CreateRadialGradientBrush(const D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES& radialGradientBrushProperties, const D2D1_BRUSH_PROPERTIES* brushProperties, ID2D1GradientStopCollection* gradientStopCollection);
                HWIN_EXPORT RadialGradientBrush CreateRadialGradientBrush(const D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES* radialGradientBrushProperties, const D2D1_BRUSH_PROPERTIES& brushProperties, ID2D1GradientStopCollection* gradientStopCollection);
                HWIN_EXPORT RadialGradientBrush CreateRadialGradientBrush(const D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES& radialGradientBrushProperties, const D2D1_BRUSH_PROPERTIES& brushProperties, ID2D1GradientStopCollection* gradientStopCollection);
    
                HWIN_EXPORT RadialGradientBrush CreateRadialGradientBrush(const D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES* radialGradientBrushProperties, ID2D1GradientStopCollection* gradientStopCollection);
                HWIN_EXPORT RadialGradientBrush CreateRadialGradientBrush(const D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES& radialGradientBrushProperties, ID2D1GradientStopCollection* gradientStopCollection);

                HWIN_EXPORT RadialGradientBrush CreateRadialGradientBrush(const D2D1_POINT_2F& center, const D2D1_POINT_2F& gradientOriginOffset, FLOAT radiusX, FLOAT radiusY, ID2D1GradientStopCollection* gradientStopCollection);

    
                //
                // Creates a bitmap render target whose bitmap can be used as a source for
                // rendering in the API.
                //
                HWIN_EXPORT BitmapRenderTarget CreateCompatibleRenderTarget(
        
                    //
                    // The requested size of the target in DIPs. If the pixel size is not specified,
                    // the DPI is inherited from the parent target. However, the render target will
                    // never contain a fractional number of pixels.
                    //
                    const D2D1_SIZE_F *desiredSize,
        
                    //
                    // The requested size of the render target in pixels. If the DIP size is also
                    // specified, the DPI is calculated from these two values. If the desired size is
                    // not specified, the DPI is inherited from the parent render target. If neither
                    // value is specified, the compatible render target will be the same size and have
                    // the same DPI as the parent target.
                    //
                    const D2D1_SIZE_U *desiredPixelSize,
        
                    //
                    // The desired pixel format. The format must be compatible with the parent render
                    // target type. If the format is not specified, it will be inherited from the
                    // parent render target.
                    //
                    const D2D1_PIXEL_FORMAT *desiredFormat,
        
                    // Allows the caller to retrieve a GDI compatible render target.
                    D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS options); 
    
                HWIN_EXPORT BitmapRenderTarget CreateCompatibleRenderTarget(const D2D1_SIZE_F* desiredSize, const D2D1_SIZE_U* desiredPixelSize, const D2D1_PIXEL_FORMAT& desiredFormat, D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS options);
                HWIN_EXPORT BitmapRenderTarget CreateCompatibleRenderTarget(const D2D1_SIZE_F* desiredSize, const D2D1_SIZE_U& desiredPixelSize, const D2D1_PIXEL_FORMAT* desiredFormat, D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS options);
                HWIN_EXPORT BitmapRenderTarget CreateCompatibleRenderTarget(const D2D1_SIZE_F* desiredSize, const D2D1_SIZE_U& desiredPixelSize, const D2D1_PIXEL_FORMAT& desiredFormat, D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS options);
                HWIN_EXPORT BitmapRenderTarget CreateCompatibleRenderTarget(const D2D1_SIZE_F& desiredSize, const D2D1_SIZE_U* desiredPixelSize, const D2D1_PIXEL_FORMAT* desiredFormat, D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS options);
                HWIN_EXPORT BitmapRenderTarget CreateCompatibleRenderTarget(const D2D1_SIZE_F& desiredSize, const D2D1_SIZE_U* desiredPixelSize, const D2D1_PIXEL_FORMAT& desiredFormat, D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS options);
                HWIN_EXPORT BitmapRenderTarget CreateCompatibleRenderTarget(const D2D1_SIZE_F& desiredSize, const D2D1_SIZE_U& desiredPixelSize, const D2D1_PIXEL_FORMAT& desiredFormat, D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS options);

                HWIN_EXPORT BitmapRenderTarget CreateCompatibleRenderTarget(const D2D1_SIZE_F* desiredSize, const D2D1_SIZE_U* desiredPixelSize, const D2D1_PIXEL_FORMAT& desiredFormat);
                HWIN_EXPORT BitmapRenderTarget CreateCompatibleRenderTarget(const D2D1_SIZE_F* desiredSize, const D2D1_SIZE_U& desiredPixelSize, const D2D1_PIXEL_FORMAT* desiredFormat);
                HWIN_EXPORT BitmapRenderTarget CreateCompatibleRenderTarget(const D2D1_SIZE_F* desiredSize, const D2D1_SIZE_U& desiredPixelSize, const D2D1_PIXEL_FORMAT& desiredFormat);
                HWIN_EXPORT BitmapRenderTarget CreateCompatibleRenderTarget(const D2D1_SIZE_F& desiredSize, const D2D1_SIZE_U* desiredPixelSize, const D2D1_PIXEL_FORMAT* desiredFormat);
                HWIN_EXPORT BitmapRenderTarget CreateCompatibleRenderTarget(const D2D1_SIZE_F& desiredSize, const D2D1_SIZE_U* desiredPixelSize, const D2D1_PIXEL_FORMAT& desiredFormat);
                HWIN_EXPORT BitmapRenderTarget CreateCompatibleRenderTarget(const D2D1_SIZE_F& desiredSize, const D2D1_SIZE_U& desiredPixelSize, const D2D1_PIXEL_FORMAT& desiredFormat);


                HWIN_EXPORT BitmapRenderTarget CreateCompatibleRenderTarget(const D2D1_SIZE_F* desiredSize, const D2D1_SIZE_U* desiredPixelSize);
                HWIN_EXPORT BitmapRenderTarget CreateCompatibleRenderTarget(const D2D1_SIZE_F* desiredSize, const D2D1_PIXEL_FORMAT* desiredFormat);
                HWIN_EXPORT BitmapRenderTarget CreateCompatibleRenderTarget(const D2D1_SIZE_F* desiredSize);
                
                HWIN_EXPORT BitmapRenderTarget CreateCompatibleRenderTarget(const D2D1_SIZE_F& desiredSize, const D2D1_SIZE_U* desiredPixelSize);
                HWIN_EXPORT BitmapRenderTarget CreateCompatibleRenderTarget(const D2D1_SIZE_F& desiredSize, const D2D1_SIZE_U& desiredPixelSize);
                HWIN_EXPORT BitmapRenderTarget CreateCompatibleRenderTarget(const D2D1_SIZE_F& desiredSize, const D2D1_PIXEL_FORMAT* desiredFormat);
                HWIN_EXPORT BitmapRenderTarget CreateCompatibleRenderTarget(const D2D1_SIZE_F& desiredSize, const D2D1_PIXEL_FORMAT& desiredFormat);
                HWIN_EXPORT BitmapRenderTarget CreateCompatibleRenderTarget(const D2D1_SIZE_F& desiredSize);

                HWIN_EXPORT BitmapRenderTarget CreateCompatibleRenderTarget( );




    
                //
                // Creates a layer resource that can be used on any target and which will resize
                // under the covers if necessary.
                //
                HWIN_EXPORT Layer CreateLayer(
                    //
                    // The resolution independent minimum size hint for the layer resource. Specify
                    // this to prevent unwanted reallocation of the layer backing store. The size is in
                    // DIPs, but, it is unaffected by the current world transform. If the size is
                    // unspecified, the returned resource is a placeholder and the backing store will
                    // be allocated to be the minimum size that can hold the content when the layer is
                    // pushed.
                    //
                    const D2D1_SIZE_F *size);

                HWIN_EXPORT Layer CreateLayer(const D2D1_SIZE_F& size);
                HWIN_EXPORT Layer CreateLayer( );
    
    
                //
                // Create a D2D mesh.
                //
                HWIN_EXPORT Mesh CreateMesh( );
    
                HWIN_EXPORT RenderTarget& DrawLine( D2D1_POINT_2F point0, D2D1_POINT_2F point1, ID2D1Brush *brush, FLOAT strokeWidth = 1.0f, ID2D1StrokeStyle *strokeStyle = NULL );
    
                HWIN_EXPORT RenderTarget& DrawRectangle(const D2D1_RECT_F* rect, ID2D1Brush *brush, FLOAT strokeWidth = 1.0f, ID2D1StrokeStyle *strokeStyle = NULL );
                HWIN_EXPORT RenderTarget& DrawRectangle(const D2D1_RECT_F& rect, ID2D1Brush *brush, FLOAT strokeWidth = 1.0f, ID2D1StrokeStyle *strokeStyle = NULL );
    
                HWIN_EXPORT RenderTarget& FillRectangle(const D2D1_RECT_F* rect, ID2D1Brush *brush );
                HWIN_EXPORT RenderTarget& FillRectangle(const D2D1_RECT_F& rect, ID2D1Brush *brush );
    
                HWIN_EXPORT RenderTarget& DrawRoundedRectangle(const D2D1_ROUNDED_RECT* roundedRect, ID2D1Brush *brush, FLOAT strokeWidth = 1.0f, ID2D1StrokeStyle *strokeStyle = NULL );
                HWIN_EXPORT RenderTarget& DrawRoundedRectangle(const D2D1_ROUNDED_RECT& roundedRect, ID2D1Brush *brush, FLOAT strokeWidth = 1.0f, ID2D1StrokeStyle *strokeStyle = NULL );
    
                HWIN_EXPORT RenderTarget& FillRoundedRectangle(const D2D1_ROUNDED_RECT* roundedRect, ID2D1Brush *brush );
                HWIN_EXPORT RenderTarget& FillRoundedRectangle(const D2D1_ROUNDED_RECT& roundedRect, ID2D1Brush *brush );
    
                HWIN_EXPORT RenderTarget& DrawEllipse(const D2D1_ELLIPSE* ellipse, ID2D1Brush *brush, FLOAT strokeWidth = 1.0f, ID2D1StrokeStyle *strokeStyle = NULL );
                HWIN_EXPORT RenderTarget& DrawEllipse(const D2D1_ELLIPSE& ellipse, ID2D1Brush *brush, FLOAT strokeWidth = 1.0f, ID2D1StrokeStyle *strokeStyle = NULL );
    
                HWIN_EXPORT RenderTarget& FillEllipse(const D2D1_ELLIPSE* ellipse, ID2D1Brush *brush );
                HWIN_EXPORT RenderTarget& FillEllipse(const D2D1_ELLIPSE& ellipse, ID2D1Brush *brush );
    
                HWIN_EXPORT RenderTarget& DrawGeometry( ID2D1Geometry *geometry, ID2D1Brush *brush, FLOAT strokeWidth = 1.0f, ID2D1StrokeStyle *strokeStyle = NULL );
    
                HWIN_EXPORT RenderTarget& FillGeometry( ID2D1Geometry *geometry, ID2D1Brush *brush,
                                                // An optionally specified opacity brush. Only the alpha channel of the
                                                // corresponding brush will be sampled and will be applied to the entire fill of
                                                // the geometry. If this brush is specified, the fill brush must be a bitmap brush
                                                // with an extend mode of D2D1_EXTEND_MODE_CLAMP.
                                                ID2D1Brush *opacityBrush = NULL );
    
    
                //
                // Fill a mesh. Since meshes can only render aliased content, the render target
                // antialiasing mode must be set to aliased.
                //
                HWIN_EXPORT RenderTarget& FillMesh(ID2D1Mesh *mesh, ID2D1Brush *brush);
    
    
                //
                // Fill using the alpha channel of the supplied opacity mask bitmap. The brush
                // opacity will be modulated by the mask. The render target antialiasing mode must
                // be set to aliased.
                //
                HWIN_EXPORT RenderTarget& FillOpacityMask(ID2D1Bitmap *opacityMask, ID2D1Brush *brush,
                                                            D2D1_OPACITY_MASK_CONTENT content, 
                                                            const D2D1_RECT_F *destinationRectangle = NULL, 
                                                            const D2D1_RECT_F *sourceRectangle = NULL );
    
                HWIN_EXPORT RenderTarget& DrawBitmap(ID2D1Bitmap *bitmap, const D2D1_RECT_F *destinationRectangle = NULL,
                                                            FLOAT opacity = 1.0f, 
                                                            D2D1_BITMAP_INTERPOLATION_MODE interpolationMode = D2D1_BITMAP_INTERPOLATION_MODE_LINEAR,
                                                            const D2D1_RECT_F *sourceRectangle = NULL );
    
    
                //
                // Draws the text within the given layout rectangle and by default also snaps and
                // clips it to the content bounds.
                //
                HWIN_EXPORT RenderTarget& DrawText( const WCHAR *string,
                                                            UINT32 stringLength,
                                                            IDWriteTextFormat *textFormat,
                                                            const D2D1_RECT_F *layoutRect,
                                                            ID2D1Brush *defaultForegroundBrush,
                                                            D2D1_DRAW_TEXT_OPTIONS options = D2D1_DRAW_TEXT_OPTIONS_NONE,
                                                            DWRITE_MEASURING_MODE measuringMode = DWRITE_MEASURING_MODE_NATURAL );
                RenderTarget& DrawText(const WCHAR *string,UINT32 stringLength,IDWriteTextFormat *textFormat,const D2D1_RECT_F &layoutRect,ID2D1Brush *defaultForegroundBrush,D2D1_DRAW_TEXT_OPTIONS options = D2D1_DRAW_TEXT_OPTIONS_NONE,DWRITE_MEASURING_MODE measuringMode = DWRITE_MEASURING_MODE_NATURAL )  
                {
                    HWIN_TRACE();
                    return DrawText(string, stringLength, textFormat, &layoutRect, defaultForegroundBrush, options, measuringMode);
                }

                HWIN_EXPORT RenderTarget& DrawText( const String& theText,
                                                            IDWriteTextFormat *textFormat,
                                                            const D2D1_RECT_F *layoutRect,
                                                            ID2D1Brush *defaultForegroundBrush,
                                                            D2D1_DRAW_TEXT_OPTIONS options = D2D1_DRAW_TEXT_OPTIONS_NONE,
                                                            DWRITE_MEASURING_MODE measuringMode = DWRITE_MEASURING_MODE_NATURAL );
    
                RenderTarget& DrawText(const String& theText,IDWriteTextFormat *textFormat,const D2D1_RECT_F &layoutRect,ID2D1Brush *defaultForegroundBrush,D2D1_DRAW_TEXT_OPTIONS options = D2D1_DRAW_TEXT_OPTIONS_NONE,DWRITE_MEASURING_MODE measuringMode = DWRITE_MEASURING_MODE_NATURAL )  
                {
                    HWIN_TRACE();
                    return DrawText(theText, textFormat, &layoutRect, defaultForegroundBrush, options, measuringMode);
                }

    
                //
                // Draw a snapped text layout object. Since the layout is not subsequently changed,
                // this can be more efficient than DrawText when drawing the same layout
                // repeatedly.
                //
                HWIN_EXPORT RenderTarget& DrawTextLayout(D2D1_POINT_2F origin,
                                                            IDWriteTextLayout *textLayout,
                                                            ID2D1Brush *defaultForegroundBrush,
        
                                                            //
                                                            // The specified text options. NOTE: By default the text is clipped to the layout
                                                            // bounds. This is derived from the origin and the layout bounds of the
                                                            // corresponding IDWriteTextLayout object.
                                                            //
                                                            D2D1_DRAW_TEXT_OPTIONS options = D2D1_DRAW_TEXT_OPTIONS_NONE );
    
                HWIN_EXPORT RenderTarget& DrawGlyphRun(D2D1_POINT_2F baselineOrigin,const DWRITE_GLYPH_RUN *glyphRun,
                                                            ID2D1Brush *foregroundBrush, 
                                                            DWRITE_MEASURING_MODE measuringMode = DWRITE_MEASURING_MODE_NATURAL );
    
                HWIN_EXPORT RenderTarget& SetTransform(const D2D1_MATRIX_3X2_F *transform );

                RenderTarget& SetTransform(const D2D1_MATRIX_3X2_F& transform )
                {
                    HWIN_TRACE();
                    return SetTransform(&transform);
                }

    
                HWIN_EXPORT const RenderTarget& GetTransform(D2D1_MATRIX_3X2_F *transform ) const;



                D2D1_MATRIX_3X2_F GetTransform( ) const
                {
                    HWIN_TRACE();
                    D2D1_MATRIX_3X2_F result = {0,};
                    GetTransform(&result);
                    return result;
                }

    
                HWIN_EXPORT RenderTarget& SetAntialiasMode( D2D1_ANTIALIAS_MODE antialiasMode );
    
                HWIN_EXPORT D2D1_ANTIALIAS_MODE GetAntialiasMode( ) const;
    
                HWIN_EXPORT RenderTarget& SetTextAntialiasMode( D2D1_TEXT_ANTIALIAS_MODE textAntialiasMode );
    
                HWIN_EXPORT D2D1_TEXT_ANTIALIAS_MODE GetTextAntialiasMode( ) const;
    
                HWIN_EXPORT RenderTarget& SetTextRenderingParams( IDWriteRenderingParams *textRenderingParams = NULL);
    
    
                //
                // Retrieve the text render parameters. NOTE: If NULL is specified to
                // SetTextRenderingParameters, NULL will be returned.
                //
                HWIN_EXPORT const RenderTarget& GetTextRenderingParams( IDWriteRenderingParams **textRenderingParams ) const;
    
    
                //
                // Set a tag to correspond to the succeeding primitives. If an error occurs
                // rendering a primitive, the tags can be returned from the Flush or EndDraw call.
                //
                HWIN_EXPORT RenderTarget& SetTags(D2D1_TAG tag1, D2D1_TAG tag2);
    
    
                //
                // Retrieves the currently set tags. This does not retrieve the tags corresponding
                // to any primitive that is in error.
                //
                HWIN_EXPORT const RenderTarget& GetTags( D2D1_TAG *tag1 = NULL, D2D1_TAG *tag2 = NULL ) const;
    
    
                //
                // Start a layer of drawing calls. The way in which the layer must be resolved is
                // specified first as well as the logical resource that stores the layer
                // parameters. The supplied layer resource might grow if the specified content
                // cannot fit inside it. The layer will grow monotonically on each axis.  If a NULL
                // ID2D1Layer is provided, then a layer resource will be allocated automatically.
                //
                HWIN_EXPORT RenderTarget& PushLayer(const D2D1_LAYER_PARAMETERS *layerParameters, ID2D1Layer *layer );
    
    
                //
                // Ends a layer that was defined with particular layer resources.
                //
                HWIN_EXPORT RenderTarget& PopLayer( );
    
                HWIN_EXPORT RenderTarget& Flush(D2D1_TAG *tag1 = NULL, D2D1_TAG *tag2 = NULL );
    
    
                //
                // Gets the current drawing state and saves it into the supplied
                // IDrawingStatckBlock.
                //
                HWIN_EXPORT RenderTarget& SaveDrawingState(ID2D1DrawingStateBlock *drawingStateBlock);
    
    
                //
                // Copies the state stored in the block interface.
                //
                HWIN_EXPORT RenderTarget& RestoreDrawingState( ID2D1DrawingStateBlock *drawingStateBlock);
    
    
                //
                // Pushes a clip. The clip can be antialiased. The clip must be axis aligned. If
                // the current world transform is not axis preserving, then the bounding box of the
                // transformed clip rect will be used. The clip will remain in effect until a
                // PopAxisAligned clip call is made.
                //
                HWIN_EXPORT RenderTarget& PushAxisAlignedClip(const D2D1_RECT_F *clipRect, D2D1_ANTIALIAS_MODE antialiasMode );
    
                HWIN_EXPORT RenderTarget& PopAxisAlignedClip( );
    
                HWIN_EXPORT RenderTarget& Clear(const D2D1_COLOR_F *clearColor = NULL);
    
    
                //
                // Start drawing on this render target. Draw calls can only be issued between a
                // BeginDraw and EndDraw call.
                //
                HWIN_EXPORT RenderTarget& BeginDraw( );
    
    
                //
                // Ends drawing on the render target, error results can be retrieved at this time,
                // or when calling flush.
                //
                HWIN_EXPORT RenderTarget& EndDraw( D2D1_TAG *tag1 = NULL, D2D1_TAG *tag2 = NULL );
    
                HWIN_EXPORT D2D1_PIXEL_FORMAT GetPixelFormat( ) const;
    
    
                //
                // Sets the DPI on the render target. This results in the render target being
                // interpreted to a different scale. Neither DPI can be negative. If zero is
                // specified for both, the system DPI is chosen. If one is zero and the other
                // unspecified, the DPI is not changed.
                //
                HWIN_EXPORT RenderTarget& SetDpi( FLOAT dpiX, FLOAT dpiY );
    
    
                //
                // Return the current DPI from the target.
                //
                HWIN_EXPORT const RenderTarget& GetDpi( FLOAT *dpiX, FLOAT *dpiY ) const;
    
    
                //
                // Returns the size of the render target in DIPs.
                //
                HWIN_EXPORT D2D1_SIZE_F GetSize( ) const;
    
    
                //
                // Returns the size of the render target in pixels.
                //
                HWIN_EXPORT D2D1_SIZE_U GetPixelSize( ) const;
    
    
                //
                // Returns the maximum bitmap and render target size that is guaranteed to be
                // supported by the render target.
                //
                HWIN_EXPORT UINT32 GetMaximumBitmapSize( ) const;
    
    
                //
                // Returns true if the given properties are supported by this render target. The
                // DPI is ignored. NOTE: If the render target type is software, then neither
                // D2D1_FEATURE_LEVEL_9 nor D2D1_FEATURE_LEVEL_10 will be considered to be
                // supported.
                //
                HWIN_EXPORT bool IsSupported(const D2D1_RENDER_TARGET_PROPERTIES *renderTargetProperties ) const;
                
    
                
                RenderTarget& FillOpacityMask(ID2D1Bitmap *opacityMask,ID2D1Brush *brush, D2D1_OPACITY_MASK_CONTENT content,const D2D1_RECT_F &destinationRectangle,const D2D1_RECT_F &sourceRectangle )
                {
                    HWIN_TRACE();
                    return FillOpacityMask(opacityMask, brush, content, &destinationRectangle, &sourceRectangle);
                }
    
                
                RenderTarget& DrawBitmap(ID2D1Bitmap *bitmap,const D2D1_RECT_F &destinationRectangle,FLOAT opacity = 1.0f, D2D1_BITMAP_INTERPOLATION_MODE interpolationMode = D2D1_BITMAP_INTERPOLATION_MODE_LINEAR,const D2D1_RECT_F *sourceRectangle = NULL)
                {
                    HWIN_TRACE();
                    return DrawBitmap(bitmap, &destinationRectangle, opacity, interpolationMode, sourceRectangle);
                }
    
                
                RenderTarget& DrawBitmap(ID2D1Bitmap *bitmap,const D2D1_RECT_F &destinationRectangle,FLOAT opacity, D2D1_BITMAP_INTERPOLATION_MODE interpolationMode,const D2D1_RECT_F &sourceRectangle )  
                {
                    HWIN_TRACE();
                    return DrawBitmap(bitmap, &destinationRectangle, opacity, interpolationMode, &sourceRectangle);
                }
    
                
                RenderTarget& PushLayer(const D2D1_LAYER_PARAMETERS &layerParameters,ID2D1Layer *layer )  
                {
                    HWIN_TRACE();
                    return PushLayer(&layerParameters, layer);
                }
    
                
                RenderTarget& PushAxisAlignedClip(const D2D1_RECT_F &clipRect,D2D1_ANTIALIAS_MODE antialiasMode )  
                {
                    HWIN_TRACE();
                    return PushAxisAlignedClip(&clipRect, antialiasMode);
                }
    
                
                RenderTarget& Clear(const D2D1_COLOR_F &clearColor )  
                {
                    HWIN_TRACE();
                    return Clear(&clearColor);
                }
    
    
                //
                // Draws the text within the given layout rectangle and by default also snaps and
                // clips it.
                //
                
                
    
                
                bool IsSupported(const D2D1_RENDER_TARGET_PROPERTIES &renderTargetProperties) const 
                {
                    HWIN_TRACE();
                    return IsSupported(&renderTargetProperties);
                }

            };

            class BitmapRenderTarget : public RenderTarget
            {
            public:
                typedef RenderTarget Base;

                HARLINN_WINDOWS_GRAPHICS_STANDARD_METHODS_IMPL(BitmapRenderTarget, RenderTarget,ID2D1BitmapRenderTarget,ID2D1RenderTarget)


                HWIN_EXPORT const BitmapRenderTarget& GetBitmap(ID2D1Bitmap **bitmap ) const;

                HWIN_EXPORT Bitmap GetBitmap( ) const;

            };


            class ControlRenderTarget : public RenderTarget
            {
            public:
                typedef RenderTarget Base;

                HARLINN_WINDOWS_GRAPHICS_STANDARD_METHODS_IMPL(ControlRenderTarget, RenderTarget,ID2D1HwndRenderTarget,ID2D1RenderTarget)

                HWIN_EXPORT D2D1_WINDOW_STATE CheckWindowState( );
    
    
                //
                // Resize the buffer underlying the render target. This operation might fail if
                // there is insufficient video memory or system memory, or if the render target is
                // resized beyond the maximum bitmap size. If the method fails, the render target
                // will be placed in a zombie state and D2DERR_RECREATE_TARGET will be returned
                // from it when EndDraw is called. In addition an appropriate failure result will
                // be returned from Resize.
                //
                HWIN_EXPORT ControlRenderTarget& Resize(const D2D1_SIZE_U *pixelSize );
    
                HWIN_EXPORT HWND GetHwnd( ) const;
    
                
                ControlRenderTarget& Resize(const D2D1_SIZE_U &pixelSize )  
                {
                    HWIN_TRACE();
                    return Resize(&pixelSize);
                }

            };

            class GdiInteropRenderTarget : public RenderTarget
            {
            public:
                typedef RenderTarget Base;

                HARLINN_WINDOWS_GRAPHICS_STANDARD_METHODS_IMPL(GdiInteropRenderTarget, RenderTarget,ID2D1GdiInteropRenderTarget,ID2D1RenderTarget)

                HWIN_EXPORT GdiInteropRenderTarget& GetDC(D2D1_DC_INITIALIZE_MODE mode, HDC *hdc );
    
                HWIN_EXPORT GdiInteropRenderTarget& ReleaseDC(const RECT *update );

            };


            class DeviceContextRenderTarget : public RenderTarget
            {
            public:
                typedef RenderTarget Base;

                HARLINN_WINDOWS_GRAPHICS_STANDARD_METHODS_IMPL(DeviceContextRenderTarget, RenderTarget,ID2D1DCRenderTarget,ID2D1RenderTarget)


                HWIN_EXPORT DeviceContextRenderTarget& BindDC(const HDC hDC,const RECT *pSubRect );

                HWIN_EXPORT DeviceContextRenderTarget& BindDC(const HDC hDC,const RECT& pSubRect );

            };





            
            class Factory : public Unknown
            {
            public:
                typedef Unknown Base;

                HARLINN_WINDOWS_GRAPHICS_STANDARD_METHODS_IMPL(Factory,Unknown,ID2D1Factory,IUnknown)

                HWIN_EXPORT Factory(D2D1_FACTORY_TYPE factoryType);


                HWIN_EXPORT Factory& ReloadSystemMetrics();

                HWIN_EXPORT const Factory& GetDesktopDpi(FLOAT *dpiX, FLOAT *dpiY) const;
                HWIN_EXPORT const Factory& GetDesktopDpi(FLOAT& dpiX, FLOAT& dpiY) const;
                HWIN_EXPORT D2D1_SIZE_F GetDesktopDpi() const;

                HWIN_EXPORT RectangleGeometry CreateRectangleGeometry(const D2D1_RECT_F* rectangle) const;
                HWIN_EXPORT RectangleGeometry CreateRectangleGeometry(const D2D1_RECT_F& rectangle) const;
                HWIN_EXPORT RectangleGeometry CreateRectangleGeometry(const D2D1_POINT_2F* position, const D2D1_SIZE_F* size) const;
                HWIN_EXPORT RectangleGeometry CreateRectangleGeometry(const D2D1_POINT_2F& position, const D2D1_SIZE_F& size) const;
                HWIN_EXPORT RectangleGeometry CreateRectangleGeometry(FLOAT left,FLOAT top,FLOAT right, FLOAT bottom) const;
                

                HWIN_EXPORT RoundedRectangleGeometry CreateRoundedRectangleGeometry(const D2D1_ROUNDED_RECT* rectangle) const;
                HWIN_EXPORT RoundedRectangleGeometry CreateRoundedRectangleGeometry(const D2D1_ROUNDED_RECT& rectangle) const;
                HWIN_EXPORT RoundedRectangleGeometry CreateRoundedRectangleGeometry(const D2D1_RECT_F* rectangle, FLOAT radiusX, FLOAT readiusY ) const;
                HWIN_EXPORT RoundedRectangleGeometry CreateRoundedRectangleGeometry(const D2D1_RECT_F& rectangle, FLOAT radiusX, FLOAT readiusY ) const;
                HWIN_EXPORT RoundedRectangleGeometry CreateRoundedRectangleGeometry(const D2D1_POINT_2F* position, const D2D1_SIZE_F* size, FLOAT radiusX, FLOAT readiusY) const;
                HWIN_EXPORT RoundedRectangleGeometry CreateRoundedRectangleGeometry(const D2D1_POINT_2F& position, const D2D1_SIZE_F& size, FLOAT radiusX, FLOAT readiusY) const;
                HWIN_EXPORT RoundedRectangleGeometry CreateRoundedRectangleGeometry(FLOAT left,FLOAT top,FLOAT right, FLOAT bottom, FLOAT radiusX, FLOAT readiusY) const;

    
                HWIN_EXPORT EllipseGeometry CreateEllipseGeometry(const D2D1_ELLIPSE *ellipse);
    
    
                //
                // Create a geometry which holds other geometries.
                //
                HWIN_EXPORT GeometryGroup CreateGeometryGroup(D2D1_FILL_MODE fillMode,ID2D1Geometry **geometries, UINT32 geometriesCount );
    
                HWIN_EXPORT TransformedGeometry CreateTransformedGeometry(ID2D1Geometry *sourceGeometry,const D2D1_MATRIX_3X2_F *transform );
    
    
                //
                // Returns an initially empty path geometry interface. A geometry sink is created
                // off the interface to populate it.
                //
                HWIN_EXPORT PathGeometry CreatePathGeometry( );
    
    
                //
                // Allows a non-default stroke style to be specified for a given geometry at draw
                // time.
                //
                HWIN_EXPORT StrokeStyle CreateStrokeStyle(const D2D1_STROKE_STYLE_PROPERTIES* strokeStyleProperties,const FLOAT* dashes, UINT32 dashesCount );
                HWIN_EXPORT StrokeStyle CreateStrokeStyle(const D2D1_STROKE_STYLE_PROPERTIES* strokeStyleProperties);
    
    
                //
                // Creates a new drawing state block, this can be used in subsequent
                // SaveDrawingState and RestoreDrawingState operations on the render target.
                //
                HWIN_EXPORT DrawingStateBlock CreateDrawingStateBlock(const D2D1_DRAWING_STATE_DESCRIPTION* drawingStateDescription, IDWriteRenderingParams* textRenderingParams );
                HWIN_EXPORT DrawingStateBlock CreateDrawingStateBlock(const D2D1_DRAWING_STATE_DESCRIPTION* drawingStateDescription  );
                HWIN_EXPORT DrawingStateBlock CreateDrawingStateBlock(const D2D1_DRAWING_STATE_DESCRIPTION& drawingStateDescription  );
                HWIN_EXPORT DrawingStateBlock CreateDrawingStateBlock(IDWriteRenderingParams *textRenderingParams );
                HWIN_EXPORT DrawingStateBlock CreateDrawingStateBlock( );
    
    
                //
                // Creates a render target which is a source of bitmaps.
                //
                HWIN_EXPORT RenderTarget CreateWicBitmapRenderTarget(IWICBitmap *target,const D2D1_RENDER_TARGET_PROPERTIES* renderTargetProperties);
                HWIN_EXPORT RenderTarget CreateWicBitmapRenderTarget(IWICBitmap *target,const D2D1_RENDER_TARGET_PROPERTIES& renderTargetProperties);

                HWIN_EXPORT ControlRenderTarget CreateControlRenderTarget( std::shared_ptr<Control> control ) const;
                HWIN_EXPORT ControlRenderTarget CreateControlRenderTarget( HWND hwnd ) const;


                //
                // Creates a render target that draws to a DXGI Surface. The device that owns the
                // surface is used for rendering.
                //
                HWIN_EXPORT RenderTarget CreateDxgiSurfaceRenderTarget(IDXGISurface *dxgiSurface,const D2D1_RENDER_TARGET_PROPERTIES* renderTargetProperties );
                HWIN_EXPORT RenderTarget CreateDxgiSurfaceRenderTarget(IDXGISurface *dxgiSurface,const D2D1_RENDER_TARGET_PROPERTIES& renderTargetProperties );
                HWIN_EXPORT RenderTarget CreateDxgiSurfaceRenderTarget(IDXGISurface *dxgiSurface );
    
    
                //
                // Creates a render target that draws to a GDI device context.
                //
                HWIN_EXPORT DeviceContextRenderTarget CreateDCRenderTarget(const D2D1_RENDER_TARGET_PROPERTIES* renderTargetProperties);
                HWIN_EXPORT DeviceContextRenderTarget CreateDCRenderTarget(const D2D1_RENDER_TARGET_PROPERTIES& renderTargetProperties);
                HWIN_EXPORT DeviceContextRenderTarget CreateDCRenderTarget( );
    
            public:
            };


            class WriteFontFileStream;
            class WriteFontFileLoader : public Unknown
            {
            public:
                typedef Unknown Base;

                HARLINN_WINDOWS_GRAPHICS_STANDARD_METHODS_IMPL(WriteFontFileLoader,Unknown,IDWriteFontFileLoader,IUnknown)

                HWIN_EXPORT WriteFontFileLoader& CreateStreamFromKey(void const* fontFileReferenceKey,UINT32 fontFileReferenceKeySize,_Out_ IDWriteFontFileStream** fontFileStream);
                HWIN_EXPORT WriteFontFileStream CreateStreamFromKey(void const* fontFileReferenceKey,UINT32 fontFileReferenceKeySize);
            };

            class WriteLocalFontFileLoader : public WriteFontFileLoader
            {
            public:
                typedef WriteFontFileLoader Base;

                HARLINN_WINDOWS_GRAPHICS_STANDARD_METHODS_IMPL(WriteLocalFontFileLoader,WriteFontFileLoader,IDWriteLocalFontFileLoader,IDWriteFontFileLoader)

                HWIN_EXPORT WriteLocalFontFileLoader& GetFilePathLengthFromKey(void const* fontFileReferenceKey,UINT32 fontFileReferenceKeySize,_Out_ UINT32* filePathLength);
                HWIN_EXPORT UINT32 GetFilePathLengthFromKey(void const* fontFileReferenceKey,UINT32 fontFileReferenceKeySize);

                HWIN_EXPORT WriteLocalFontFileLoader& GetFilePathFromKey(void const* fontFileReferenceKey,UINT32 fontFileReferenceKeySize, WCHAR* filePath,UINT32 filePathSize);
                HWIN_EXPORT std::shared_ptr<String> GetFilePathFromKey(void const* fontFileReferenceKey,UINT32 fontFileReferenceKeySize);

                HWIN_EXPORT WriteLocalFontFileLoader& GetLastWriteTimeFromKey(void const* fontFileReferenceKey,UINT32 fontFileReferenceKeySize,_Out_ FILETIME* lastWriteTime);
                HWIN_EXPORT FILETIME GetLastWriteTimeFromKey(void const* fontFileReferenceKey,UINT32 fontFileReferenceKeySize);
            };

            class WriteFontFileStream : public Unknown
            {
            public:
                typedef Unknown Base;

                HARLINN_WINDOWS_GRAPHICS_STANDARD_METHODS_IMPL(WriteFontFileStream,Unknown,IDWriteFontFileStream,IUnknown)

                HWIN_EXPORT WriteFontFileStream& ReadFileFragment(void const** fragmentStart,UINT64 fileOffset,UINT64 fragmentSize,_Out_ void** fragmentContext);
                HWIN_EXPORT WriteFontFileStream& ReleaseFileFragment(void* fragmentContext);

                HWIN_EXPORT WriteFontFileStream& GetFileSize(_Out_ UINT64* fileSize);
                HWIN_EXPORT UINT64 GetFileSize( );

                HWIN_EXPORT WriteFontFileStream& GetLastWriteTime(_Out_ UINT64* lastWriteTime);
                HWIN_EXPORT UINT64 GetLastWriteTime();
            };


            class WriteFontFile : public Unknown
            {
            public:
                typedef Unknown Base;

                HARLINN_WINDOWS_GRAPHICS_STANDARD_METHODS_IMPL(WriteFontFile,Unknown,IDWriteFontFile,IUnknown)

                HWIN_EXPORT WriteFontFile& GetReferenceKey(void const** fontFileReferenceKey,_Out_ UINT32* fontFileReferenceKeySize);
                HWIN_EXPORT WriteFontFile& GetLoader(_Out_ IDWriteFontFileLoader** fontFileLoader);
                HWIN_EXPORT WriteFontFileLoader GetLoader( );
                HWIN_EXPORT WriteFontFile& Analyze(_Out_ BOOL* isSupportedFontType,_Out_ DWRITE_FONT_FILE_TYPE* fontFileType, _Out_opt_ DWRITE_FONT_FACE_TYPE* fontFaceType, _Out_ UINT32* numberOfFaces);
                HWIN_EXPORT WriteFontFile& Analyze(_Out_ BOOL& isSupportedFontType,_Out_ DWRITE_FONT_FILE_TYPE& fontFileType, _Out_opt_ DWRITE_FONT_FACE_TYPE& fontFaceType, _Out_ UINT32& numberOfFaces);
                HWIN_EXPORT WriteFontFile& Analyze(_Out_ BOOL& isSupportedFontType,_Out_ DWRITE_FONT_FILE_TYPE& fontFileType, _Out_ UINT32& numberOfFaces);
            };


            class WriteRenderingParams : public Unknown
            {
            public:
                typedef Unknown Base;

                HARLINN_WINDOWS_GRAPHICS_STANDARD_METHODS_IMPL(WriteRenderingParams,Unknown,IDWriteRenderingParams,IUnknown)

                HWIN_EXPORT FLOAT GetGamma();
                HWIN_EXPORT FLOAT GetEnhancedContrast();
                HWIN_EXPORT FLOAT GetClearTypeLevel();
                HWIN_EXPORT DWRITE_PIXEL_GEOMETRY GetPixelGeometry();
                HWIN_EXPORT DWRITE_RENDERING_MODE GetRenderingMode();
            };



            class WriteFontFace : public Unknown
            {
            public:
                typedef Unknown Base;

                HARLINN_WINDOWS_GRAPHICS_STANDARD_METHODS_IMPL(WriteFontFace,Unknown,IDWriteFontFace,IUnknown)

                HWIN_EXPORT DWRITE_FONT_FACE_TYPE GetType();
                HWIN_EXPORT WriteFontFace& GetFiles(_Inout_ UINT32* numberOfFiles, IDWriteFontFile** fontFiles);
                HWIN_EXPORT UINT32 GetNumberOfFiles( );
                HWIN_EXPORT std::shared_ptr< std::vector<WriteFontFile> > GetFiles( );

                HWIN_EXPORT UINT32 GetIndex();
                HWIN_EXPORT DWRITE_FONT_SIMULATIONS GetSimulations();
                HWIN_EXPORT BOOL IsSymbolFont();
                HWIN_EXPORT WriteFontFace& GetMetrics(_Out_ DWRITE_FONT_METRICS* fontFaceMetrics);
                HWIN_EXPORT WriteFontFace& GetMetrics(_Out_ DWRITE_FONT_METRICS& fontFaceMetrics);
                HWIN_EXPORT UINT16 GetGlyphCount();
                HWIN_EXPORT WriteFontFace& GetDesignGlyphMetrics(UINT16 const* glyphIndices, UINT32 glyphCount, DWRITE_GLYPH_METRICS* glyphMetrics, BOOL isSideways = FALSE);
                HWIN_EXPORT WriteFontFace& GetGlyphIndices(UINT32 const* codePoints, UINT32 codePointCount, UINT16* glyphIndices);
                HWIN_EXPORT WriteFontFace& TryGetFontTable( _In_ UINT32 openTypeTableTag, const void** tableData, _Out_ UINT32* tableSize, _Out_ void** tableContext, _Out_ BOOL* exists);
                HWIN_EXPORT WriteFontFace& ReleaseFontTable(_In_ void* tableContext);
                HWIN_EXPORT WriteFontFace& GetGlyphRunOutline(FLOAT emSize, UINT16 const* glyphIndices, FLOAT const* glyphAdvances, DWRITE_GLYPH_OFFSET const* glyphOffsets, UINT32 glyphCount, BOOL isSideways, BOOL isRightToLeft, IDWriteGeometrySink* geometrySink);
                HWIN_EXPORT WriteFontFace& GetRecommendedRenderingMode(FLOAT emSize, FLOAT pixelsPerDip, DWRITE_MEASURING_MODE measuringMode, IDWriteRenderingParams* renderingParams, _Out_ DWRITE_RENDERING_MODE* renderingMode);
                HWIN_EXPORT DWRITE_RENDERING_MODE GetRecommendedRenderingMode(FLOAT emSize, FLOAT pixelsPerDip, DWRITE_MEASURING_MODE measuringMode, IDWriteRenderingParams* renderingParams);

                HWIN_EXPORT WriteFontFace& GetGdiCompatibleMetrics(FLOAT emSize,FLOAT pixelsPerDip,_In_opt_ DWRITE_MATRIX const* transform, _Out_ DWRITE_FONT_METRICS* fontFaceMetrics);
                HWIN_EXPORT WriteFontFace& GetGdiCompatibleGlyphMetrics( FLOAT emSize, FLOAT pixelsPerDip, _In_opt_ DWRITE_MATRIX const* transform, BOOL useGdiNatural, UINT16 const* glyphIndices, UINT32 glyphCount, DWRITE_GLYPH_METRICS* glyphMetrics, BOOL isSideways = FALSE);
            };

            class WriteFontFileEnumerator;
            class WriteFontCollectionLoader : public Unknown
            {
            public:
                typedef Unknown Base;

                HARLINN_WINDOWS_GRAPHICS_STANDARD_METHODS_IMPL(WriteFontCollectionLoader,Unknown,IDWriteFontCollectionLoader,IUnknown)

                HWIN_EXPORT WriteFontCollectionLoader& CreateEnumeratorFromKey(IDWriteFactory* factory,void const* collectionKey,UINT32 collectionKeySize, _Out_ IDWriteFontFileEnumerator** fontFileEnumerator);
                HWIN_EXPORT WriteFontFileEnumerator CreateEnumeratorFromKey(IDWriteFactory* factory,void const* collectionKey,UINT32 collectionKeySize);
            };

            class WriteFontFileEnumerator : public Unknown
            {
            public:
                typedef Unknown Base;

                HARLINN_WINDOWS_GRAPHICS_STANDARD_METHODS_IMPL(WriteFontFileEnumerator,Unknown,IDWriteFontFileEnumerator,IUnknown)

                HWIN_EXPORT WriteFontFileEnumerator& MoveNext(_Out_ BOOL* hasCurrentFile);
                HWIN_EXPORT bool MoveNext( );

                HWIN_EXPORT WriteFontFileEnumerator& GetCurrentFontFile(_Out_ IDWriteFontFile** fontFile);
                HWIN_EXPORT WriteFontFile GetCurrentFontFile();
            };


            class WriteLocalizedStrings : public Unknown
            {
            public:
                typedef Unknown Base;

                HARLINN_WINDOWS_GRAPHICS_STANDARD_METHODS_IMPL(WriteLocalizedStrings,Unknown,IDWriteLocalizedStrings,IUnknown)

                HWIN_EXPORT UINT32 GetCount();
                HWIN_EXPORT WriteLocalizedStrings& FindLocaleName(_In_z_ WCHAR const* localeName,_Out_ UINT32* index,_Out_ BOOL* exists);
                HWIN_EXPORT bool FindLocaleName(_In_z_ WCHAR const* localeName,_Out_ UINT32* index);

                HWIN_EXPORT WriteLocalizedStrings& GetLocaleNameLength(UINT32 index,_Out_ UINT32* length);
                HWIN_EXPORT UINT32 GetLocaleNameLength(UINT32 index);

                HWIN_EXPORT WriteLocalizedStrings& GetLocaleName(UINT32 index,WCHAR* localeName, UINT32 size);
                HWIN_EXPORT std::shared_ptr<String> GetLocaleName(UINT32 index);

                HWIN_EXPORT WriteLocalizedStrings& GetStringLength(UINT32 index,_Out_ UINT32* length);
                HWIN_EXPORT UINT32 GetStringLength(UINT32 index);

                HWIN_EXPORT WriteLocalizedStrings& GetString(UINT32 index,WCHAR* stringBuffer,UINT32 size);
                HWIN_EXPORT std::shared_ptr<String> GetString(UINT32 index);
            };

            class WriteFontFamily;
            class WriteFont;
            class WriteFontCollection : public Unknown
            {
            public:
                typedef Unknown Base;

                HARLINN_WINDOWS_GRAPHICS_STANDARD_METHODS_IMPL(WriteFontCollection,Unknown,IDWriteFontCollection,IUnknown)

                HWIN_EXPORT UINT32 GetFontFamilyCount();
                HWIN_EXPORT WriteFontCollection& GetFontFamily( UINT32 index, IDWriteFontFamily** fontFamily);
                HWIN_EXPORT WriteFontFamily GetFontFamily( UINT32 index );
                HWIN_EXPORT std::shared_ptr< std::vector<WriteFontFamily> > GetFontFamilies();

                HWIN_EXPORT WriteFontCollection& FindFamilyName(_In_z_ WCHAR const* familyName,_Out_ UINT32* index,_Out_ BOOL* exists);
                HWIN_EXPORT bool FindFamilyName(_In_z_ WCHAR const* familyName,_Out_ UINT32* index);

                HWIN_EXPORT WriteFontCollection& GetFontFromFontFace(IDWriteFontFace* fontFace,_Out_ IDWriteFont** font);
                HWIN_EXPORT WriteFont GetFontFromFontFace(IDWriteFontFace* fontFace);
            };

            class WriteFontList : public Unknown
            {
            public:
                typedef Unknown Base;

                HARLINN_WINDOWS_GRAPHICS_STANDARD_METHODS_IMPL(WriteFontList,Unknown,IDWriteFontList,IUnknown)

                HWIN_EXPORT WriteFontList& GetFontCollection(_Out_ IDWriteFontCollection** fontCollection);
                HWIN_EXPORT WriteFontCollection GetFontCollection( );
                HWIN_EXPORT UINT32 GetFontCount();
                HWIN_EXPORT WriteFontList& GetFont(UINT32 index, _Out_ IDWriteFont** font);
                HWIN_EXPORT WriteFont GetFont(UINT32 index);
            };


            class WriteFontFamily : public WriteFontList
            {
            public:
                typedef WriteFontList Base;

                HARLINN_WINDOWS_GRAPHICS_STANDARD_METHODS_IMPL(WriteFontFamily,WriteFontList,IDWriteFontFamily,IDWriteFontList)

                HWIN_EXPORT WriteFontFamily& GetFamilyNames(_Out_ IDWriteLocalizedStrings** names);
                HWIN_EXPORT WriteLocalizedStrings GetFamilyNames( );

                HWIN_EXPORT WriteFontFamily& GetFirstMatchingFont(DWRITE_FONT_WEIGHT  weight,DWRITE_FONT_STRETCH stretch,DWRITE_FONT_STYLE style,_Out_ IDWriteFont** matchingFont);
                HWIN_EXPORT WriteFont GetFirstMatchingFont(DWRITE_FONT_WEIGHT  weight,DWRITE_FONT_STRETCH stretch,DWRITE_FONT_STYLE style);

                HWIN_EXPORT WriteFontFamily& GetMatchingFonts(DWRITE_FONT_WEIGHT weight,DWRITE_FONT_STRETCH stretch,DWRITE_FONT_STYLE style,_Out_ IDWriteFontList** matchingFonts);
                HWIN_EXPORT WriteFontList GetMatchingFonts(DWRITE_FONT_WEIGHT weight,DWRITE_FONT_STRETCH stretch,DWRITE_FONT_STYLE style);
            };


            class WriteFont : public Unknown
            {
            public:
                typedef Unknown Base;

                HARLINN_WINDOWS_GRAPHICS_STANDARD_METHODS_IMPL(WriteFont,Unknown,IDWriteFont,IUnknown)

                HWIN_EXPORT WriteFont& GetFontFamily(_Out_ IDWriteFontFamily** fontFamily);
                HWIN_EXPORT WriteFontFamily GetFontFamily( );
                HWIN_EXPORT DWRITE_FONT_WEIGHT GetWeight();
                HWIN_EXPORT DWRITE_FONT_STRETCH GetStretch();
                HWIN_EXPORT DWRITE_FONT_STYLE GetStyle();
                HWIN_EXPORT bool IsSymbolFont();
                HWIN_EXPORT WriteFont& GetFaceNames(_Out_ IDWriteLocalizedStrings** names);
                HWIN_EXPORT WriteLocalizedStrings GetFaceNames();
                HWIN_EXPORT WriteFont& GetInformationalStrings(DWRITE_INFORMATIONAL_STRING_ID informationalStringID,_Out_ IDWriteLocalizedStrings** informationalStrings,_Out_ BOOL* exists);
                HWIN_EXPORT DWRITE_FONT_SIMULATIONS GetSimulations();
                HWIN_EXPORT WriteFont& GetMetrics(_Out_ DWRITE_FONT_METRICS* fontMetrics);
                HWIN_EXPORT WriteFont& HasCharacter(UINT32 unicodeValue,_Out_ BOOL* exists);
                HWIN_EXPORT bool HasCharacter(UINT32 unicodeValue);
                HWIN_EXPORT WriteFont& CreateFontFace(_Out_ IDWriteFontFace** fontFace);
                HWIN_EXPORT WriteFontFace CreateFontFace( );
            };


            class WriteInlineObject;
            class WriteTextFormat : public Unknown
            {
            public:
                typedef Unknown Base;

                HARLINN_WINDOWS_GRAPHICS_STANDARD_METHODS_IMPL(WriteTextFormat,Unknown,IDWriteTextFormat,IUnknown)

                HWIN_EXPORT WriteTextFormat& SetTextAlignment(DWRITE_TEXT_ALIGNMENT textAlignment);
                HWIN_EXPORT WriteTextFormat& SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT paragraphAlignment);
                HWIN_EXPORT WriteTextFormat& SetWordWrapping(DWRITE_WORD_WRAPPING wordWrapping);
                HWIN_EXPORT WriteTextFormat& SetReadingDirection(DWRITE_READING_DIRECTION readingDirection);
                HWIN_EXPORT WriteTextFormat& SetFlowDirection(DWRITE_FLOW_DIRECTION flowDirection);
                HWIN_EXPORT WriteTextFormat& SetIncrementalTabStop(FLOAT incrementalTabStop);
                HWIN_EXPORT WriteTextFormat& SetTrimming(_In_ DWRITE_TRIMMING const* trimmingOptions,IDWriteInlineObject* trimmingSign);
                HWIN_EXPORT WriteTextFormat& SetLineSpacing(DWRITE_LINE_SPACING_METHOD lineSpacingMethod,FLOAT lineSpacing,FLOAT baseline);
                HWIN_EXPORT DWRITE_TEXT_ALIGNMENT GetTextAlignment();
                HWIN_EXPORT DWRITE_PARAGRAPH_ALIGNMENT GetParagraphAlignment();
                HWIN_EXPORT DWRITE_WORD_WRAPPING GetWordWrapping();
                HWIN_EXPORT DWRITE_READING_DIRECTION GetReadingDirection();
                HWIN_EXPORT DWRITE_FLOW_DIRECTION GetFlowDirection();
                HWIN_EXPORT FLOAT GetIncrementalTabStop();
                HWIN_EXPORT WriteTextFormat& GetTrimming(_Out_ DWRITE_TRIMMING* trimmingOptions,_Out_ IDWriteInlineObject** trimmingSign);
                HWIN_EXPORT WriteInlineObject GetTrimming(_Out_ DWRITE_TRIMMING& trimmingOptions);
                HWIN_EXPORT WriteTextFormat& GetLineSpacing(_Out_ DWRITE_LINE_SPACING_METHOD* lineSpacingMethod,_Out_ FLOAT* lineSpacing,_Out_ FLOAT* baseline);
                HWIN_EXPORT WriteTextFormat& GetFontCollection(_Out_ IDWriteFontCollection** fontCollection);
                HWIN_EXPORT WriteFontCollection GetFontCollection( );
                HWIN_EXPORT UINT32 GetFontFamilyNameLength();
                HWIN_EXPORT WriteTextFormat& GetFontFamilyName(WCHAR* fontFamilyName,UINT32 nameSize);
                HWIN_EXPORT std::shared_ptr<String> GetFontFamilyName( );
                HWIN_EXPORT DWRITE_FONT_WEIGHT GetFontWeight();
                HWIN_EXPORT DWRITE_FONT_STYLE GetFontStyle();
                HWIN_EXPORT DWRITE_FONT_STRETCH GetFontStretch();
                HWIN_EXPORT FLOAT GetFontSize();
                HWIN_EXPORT UINT32 GetLocaleNameLength();
                HWIN_EXPORT WriteTextFormat& GetLocaleName(WCHAR* localeName,UINT32 nameSize);
                HWIN_EXPORT std::shared_ptr<String> GetLocaleName( );
            };


            class WriteTypography : public Unknown
            {
            public:
                typedef Unknown Base;

                HARLINN_WINDOWS_GRAPHICS_STANDARD_METHODS_IMPL(WriteTypography,Unknown,IDWriteTypography,IUnknown)

                HWIN_EXPORT WriteTypography& AddFontFeature(DWRITE_FONT_FEATURE fontFeature);
                HWIN_EXPORT WriteTypography& AddFontFeatures(std::shared_ptr< std::vector<DWRITE_FONT_FEATURE> > fontFeatures);
                HWIN_EXPORT UINT32 GetFontFeatureCount();
                HWIN_EXPORT WriteTypography& GetFontFeature(UINT32 fontFeatureIndex,_Out_ DWRITE_FONT_FEATURE* fontFeature);
                HWIN_EXPORT DWRITE_FONT_FEATURE GetFontFeature(UINT32 fontFeatureIndex);
                HWIN_EXPORT std::shared_ptr< std::vector<DWRITE_FONT_FEATURE> > GetFontFeatures( );
            };


            class WriteTextAnalysisSource : public Unknown
            {
            public:
                typedef Unknown Base;

                HARLINN_WINDOWS_GRAPHICS_STANDARD_METHODS_IMPL(WriteTextAnalysisSource,Unknown,IDWriteTextAnalysisSource,IUnknown)

                HWIN_EXPORT WriteTextAnalysisSource& GetTextAtPosition(UINT32 textPosition,WCHAR const** textString,_Out_ UINT32* textLength);
                HWIN_EXPORT WriteTextAnalysisSource& GetTextBeforePosition(UINT32 textPosition,WCHAR const** textString,_Out_ UINT32* textLength);
                HWIN_EXPORT DWRITE_READING_DIRECTION GetParagraphReadingDirection();
                HWIN_EXPORT WriteTextAnalysisSource& GetLocaleName(UINT32 textPosition,_Out_ UINT32* textLength, _Outptr_result_z_ WCHAR const** localeName);
                HWIN_EXPORT WriteTextAnalysisSource& GetNumberSubstitution(UINT32 textPosition,_Out_ UINT32* textLength,_Outptr_ IDWriteNumberSubstitution** numberSubstitution);
            };


            class WriteTextAnalysisSink : public Unknown
            {
            public:
                typedef Unknown Base;

                HARLINN_WINDOWS_GRAPHICS_STANDARD_METHODS_IMPL(WriteTextAnalysisSink,Unknown,IDWriteTextAnalysisSink,IUnknown)

                HWIN_EXPORT WriteTextAnalysisSink& SetScriptAnalysis(UINT32 textPosition,UINT32 textLength,_In_ DWRITE_SCRIPT_ANALYSIS const* scriptAnalysis);
                HWIN_EXPORT WriteTextAnalysisSink& SetLineBreakpoints(UINT32 textPosition,UINT32 textLength,DWRITE_LINE_BREAKPOINT const* lineBreakpoints);
                HWIN_EXPORT WriteTextAnalysisSink& SetBidiLevel(UINT32 textPosition,UINT32 textLength,UINT8 explicitLevel,UINT8 resolvedLevel);
                HWIN_EXPORT WriteTextAnalysisSink& SetNumberSubstitution(UINT32 textPosition,UINT32 textLength,_In_ IDWriteNumberSubstitution* numberSubstitution);
            };

            class WriteTextAnalyzer : public Unknown
            {
            public:
                typedef Unknown Base;

                HARLINN_WINDOWS_GRAPHICS_STANDARD_METHODS_IMPL(WriteTextAnalyzer,Unknown,IDWriteTextAnalyzer,IUnknown)

                HWIN_EXPORT WriteTextAnalyzer& AnalyzeScript(
                    IDWriteTextAnalysisSource* analysisSource,
                    UINT32 textPosition,
                    UINT32 textLength,
                    IDWriteTextAnalysisSink* analysisSink);

                HWIN_EXPORT WriteTextAnalyzer& AnalyzeBidi(
                    IDWriteTextAnalysisSource* analysisSource,
                    UINT32 textPosition,
                    UINT32 textLength,
                    IDWriteTextAnalysisSink* analysisSink);

                HWIN_EXPORT WriteTextAnalyzer& AnalyzeNumberSubstitution(
                    IDWriteTextAnalysisSource* analysisSource,
                    UINT32 textPosition,
                    UINT32 textLength,
                    IDWriteTextAnalysisSink* analysisSink);

                HWIN_EXPORT WriteTextAnalyzer& AnalyzeLineBreakpoints(
                    IDWriteTextAnalysisSource* analysisSource,
                    UINT32 textPosition,
                    UINT32 textLength,
                    IDWriteTextAnalysisSink* analysisSink);

                HWIN_EXPORT WriteTextAnalyzer& GetGlyphs(
                    WCHAR const* textString,
                    UINT32 textLength,
                    IDWriteFontFace* fontFace,
                    BOOL isSideways,
                    BOOL isRightToLeft,
                    _In_ DWRITE_SCRIPT_ANALYSIS const* scriptAnalysis,
                    _In_opt_z_ WCHAR const* localeName,
                    _In_opt_ IDWriteNumberSubstitution* numberSubstitution,
                    DWRITE_TYPOGRAPHIC_FEATURES const** features,
                    UINT32 const* featureRangeLengths,
                    UINT32 featureRanges,
                    UINT32 maxGlyphCount,
                    UINT16* clusterMap,
                    DWRITE_SHAPING_TEXT_PROPERTIES* textProps,
                    UINT16* glyphIndices,
                    DWRITE_SHAPING_GLYPH_PROPERTIES* glyphProps,
                    _Out_ UINT32* actualGlyphCount);

                HWIN_EXPORT WriteTextAnalyzer& GetGlyphPlacements(
                    WCHAR const* textString,
                    UINT16 const* clusterMap,
                    DWRITE_SHAPING_TEXT_PROPERTIES* textProps,
                    UINT32 textLength,
                    UINT16 const* glyphIndices,
                    DWRITE_SHAPING_GLYPH_PROPERTIES const* glyphProps,
                    UINT32 glyphCount,
                    IDWriteFontFace * fontFace,
                    FLOAT fontEmSize,
                    BOOL isSideways,
                    BOOL isRightToLeft,
                    _In_ DWRITE_SCRIPT_ANALYSIS const* scriptAnalysis,
                    _In_opt_z_ WCHAR const* localeName,
                    DWRITE_TYPOGRAPHIC_FEATURES const** features,
                    UINT32 const* featureRangeLengths,
                    UINT32 featureRanges,
                    FLOAT* glyphAdvances,
                    DWRITE_GLYPH_OFFSET* glyphOffsets);

                HWIN_EXPORT WriteTextAnalyzer& GetGdiCompatibleGlyphPlacements(
                    WCHAR const* textString,
                    UINT16 const* clusterMap,
                    DWRITE_SHAPING_TEXT_PROPERTIES* textProps,
                    UINT32 textLength,
                    UINT16 const* glyphIndices,
                    DWRITE_SHAPING_GLYPH_PROPERTIES const* glyphProps,
                    UINT32 glyphCount,
                    IDWriteFontFace * fontFace,
                    FLOAT fontEmSize,
                    FLOAT pixelsPerDip,
                    _In_opt_ DWRITE_MATRIX const* transform,
                    BOOL useGdiNatural,
                    BOOL isSideways,
                    BOOL isRightToLeft,
                    _In_ DWRITE_SCRIPT_ANALYSIS const* scriptAnalysis,
                    _In_opt_z_ WCHAR const* localeName,
                    DWRITE_TYPOGRAPHIC_FEATURES const** features,
                    UINT32 const* featureRangeLengths,
                    UINT32 featureRanges,
                    FLOAT* glyphAdvances,
                    DWRITE_GLYPH_OFFSET* glyphOffsets);
            };

            class WriteInlineObject : public Unknown
            {
            public:
                typedef Unknown Base;

                HARLINN_WINDOWS_GRAPHICS_STANDARD_METHODS_IMPL(WriteInlineObject,Unknown,IDWriteInlineObject,IUnknown)

                HWIN_EXPORT WriteInlineObject& Draw(_In_opt_ void* clientDrawingContext,IDWriteTextRenderer* renderer,FLOAT originX,FLOAT originY,BOOL isSideways,BOOL isRightToLeft,_In_opt_ IUnknown* clientDrawingEffect);

                HWIN_EXPORT WriteInlineObject& GetMetrics(_Out_ DWRITE_INLINE_OBJECT_METRICS* metrics);

                HWIN_EXPORT WriteInlineObject& GetOverhangMetrics(_Out_ DWRITE_OVERHANG_METRICS* overhangs);

                HWIN_EXPORT WriteInlineObject& GetBreakConditions(_Out_ DWRITE_BREAK_CONDITION* breakConditionBefore,_Out_ DWRITE_BREAK_CONDITION* breakConditionAfter);
            };

            class WritePixelSnapping : public Unknown
            {
            public:
                typedef Unknown Base;

                HARLINN_WINDOWS_GRAPHICS_STANDARD_METHODS_IMPL(WritePixelSnapping,Unknown,IDWritePixelSnapping,IUnknown)

                HWIN_EXPORT WritePixelSnapping& IsPixelSnappingDisabled(_In_opt_ void* clientDrawingContext,_Out_ BOOL* isDisabled);

                HWIN_EXPORT WritePixelSnapping& GetCurrentTransform(_In_opt_ void* clientDrawingContext,_Out_ DWRITE_MATRIX* transform);

                HWIN_EXPORT WritePixelSnapping& GetPixelsPerDip(_In_opt_ void* clientDrawingContext,_Out_ FLOAT* pixelsPerDip);
            };


            class WriteTextRenderer : public WritePixelSnapping
            {
            public:
                typedef WritePixelSnapping Base;

                HARLINN_WINDOWS_GRAPHICS_STANDARD_METHODS_IMPL(WriteTextRenderer,WritePixelSnapping,IDWriteTextRenderer,IDWritePixelSnapping)

                HWIN_EXPORT WriteTextRenderer& DrawGlyphRun(_In_opt_ void* clientDrawingContext,FLOAT baselineOriginX,FLOAT baselineOriginY,DWRITE_MEASURING_MODE measuringMode,_In_ DWRITE_GLYPH_RUN const* glyphRun,_In_ DWRITE_GLYPH_RUN_DESCRIPTION const* glyphRunDescription,_In_opt_ IUnknown* clientDrawingEffect);

                HWIN_EXPORT WriteTextRenderer& DrawUnderline(_In_opt_ void* clientDrawingContext,FLOAT baselineOriginX,FLOAT baselineOriginY,_In_ DWRITE_UNDERLINE const* underline,_In_opt_ IUnknown* clientDrawingEffect);

                HWIN_EXPORT WriteTextRenderer& DrawStrikethrough(_In_opt_ void* clientDrawingContext,FLOAT baselineOriginX,FLOAT baselineOriginY,_In_ DWRITE_STRIKETHROUGH const* strikethrough,_In_opt_ IUnknown* clientDrawingEffect);

                HWIN_EXPORT WriteTextRenderer& DrawInlineObject(_In_opt_ void* clientDrawingContext,FLOAT originX,FLOAT originY,IDWriteInlineObject* inlineObject,BOOL isSideways,BOOL isRightToLeft,_In_opt_ IUnknown* clientDrawingEffect);
            };


            class WriteTextLayout : public WriteTextFormat
            {
            public:
                typedef Unknown Base;

                HARLINN_WINDOWS_GRAPHICS_STANDARD_METHODS_IMPL(WriteTextLayout,WriteTextFormat,IDWriteTextLayout,IDWriteTextFormat)

                HWIN_EXPORT WriteTextLayout& SetMaxWidth(FLOAT maxWidth);
                HWIN_EXPORT WriteTextLayout& SetMaxHeight(FLOAT maxHeight);

                HWIN_EXPORT WriteTextLayout& SetFontCollection(IDWriteFontCollection* fontCollection,DWRITE_TEXT_RANGE textRange);

                HWIN_EXPORT WriteTextLayout& SetFontFamilyName(_In_z_ WCHAR const* fontFamilyName,DWRITE_TEXT_RANGE textRange);

                HWIN_EXPORT WriteTextLayout& SetFontWeight(DWRITE_FONT_WEIGHT fontWeight,DWRITE_TEXT_RANGE textRange);

                HWIN_EXPORT WriteTextLayout& SetFontStyle(DWRITE_FONT_STYLE fontStyle,DWRITE_TEXT_RANGE textRange);

                HWIN_EXPORT WriteTextLayout& SetFontStretch(DWRITE_FONT_STRETCH fontStretch,DWRITE_TEXT_RANGE textRange);

                HWIN_EXPORT WriteTextLayout& SetFontSize(FLOAT fontSize,DWRITE_TEXT_RANGE textRange);

                HWIN_EXPORT WriteTextLayout& SetUnderline(BOOL hasUnderline,DWRITE_TEXT_RANGE textRange);

                HWIN_EXPORT WriteTextLayout& SetStrikethrough(BOOL hasStrikethrough,DWRITE_TEXT_RANGE textRange);

                HWIN_EXPORT WriteTextLayout& SetDrawingEffect(IUnknown* drawingEffect,DWRITE_TEXT_RANGE textRange);

                HWIN_EXPORT WriteTextLayout& SetInlineObject(IDWriteInlineObject* inlineObject,DWRITE_TEXT_RANGE textRange);

                HWIN_EXPORT WriteTextLayout& SetTypography(IDWriteTypography* typography,DWRITE_TEXT_RANGE textRange);

                HWIN_EXPORT WriteTextLayout& SetLocaleName(_In_z_ WCHAR const* localeName,DWRITE_TEXT_RANGE textRange);

                HWIN_EXPORT FLOAT GetMaxWidth();

                HWIN_EXPORT FLOAT GetMaxHeight();

                HWIN_EXPORT WriteTextLayout& GetFontCollection(UINT32 currentPosition,_Out_ IDWriteFontCollection** fontCollection,_Out_opt_ DWRITE_TEXT_RANGE* textRange = NULL);

                HWIN_EXPORT WriteTextLayout& GetFontFamilyNameLength(UINT32 currentPosition,_Out_ UINT32* nameLength,_Out_opt_ DWRITE_TEXT_RANGE* textRange = NULL);

                HWIN_EXPORT WriteTextLayout& GetFontFamilyName(UINT32 currentPosition,_Out_writes_z_(nameSize) WCHAR* fontFamilyName,UINT32 nameSize,_Out_opt_ DWRITE_TEXT_RANGE* textRange = NULL);

                HWIN_EXPORT WriteTextLayout& GetFontWeight(UINT32 currentPosition,_Out_ DWRITE_FONT_WEIGHT* fontWeight,_Out_opt_ DWRITE_TEXT_RANGE* textRange = NULL);

                HWIN_EXPORT WriteTextLayout& GetFontStyle(UINT32 currentPosition,_Out_ DWRITE_FONT_STYLE* fontStyle,_Out_opt_ DWRITE_TEXT_RANGE* textRange = NULL);

                HWIN_EXPORT WriteTextLayout& GetFontStretch(UINT32 currentPosition,_Out_ DWRITE_FONT_STRETCH* fontStretch,_Out_opt_ DWRITE_TEXT_RANGE* textRange = NULL);

                HWIN_EXPORT WriteTextLayout& GetFontSize(UINT32 currentPosition,_Out_ FLOAT* fontSize,_Out_opt_ DWRITE_TEXT_RANGE* textRange = NULL);

                HWIN_EXPORT WriteTextLayout& GetUnderline(UINT32 currentPosition,_Out_ BOOL* hasUnderline,_Out_opt_ DWRITE_TEXT_RANGE* textRange = NULL);

                HWIN_EXPORT WriteTextLayout& GetStrikethrough(UINT32 currentPosition,_Out_ BOOL* hasStrikethrough,_Out_opt_ DWRITE_TEXT_RANGE* textRange = NULL);

                HWIN_EXPORT WriteTextLayout& GetDrawingEffect(UINT32 currentPosition,_Out_ IUnknown** drawingEffect,_Out_opt_ DWRITE_TEXT_RANGE* textRange = NULL);

                HWIN_EXPORT WriteTextLayout& GetInlineObject(UINT32 currentPosition,_Out_ IDWriteInlineObject** inlineObject,_Out_opt_ DWRITE_TEXT_RANGE* textRange = NULL);

                HWIN_EXPORT WriteTextLayout& GetTypography(UINT32 currentPosition,_Out_ IDWriteTypography** typography,_Out_opt_ DWRITE_TEXT_RANGE* textRange = NULL);

                HWIN_EXPORT WriteTextLayout& GetLocaleNameLength(UINT32 currentPosition,_Out_ UINT32* nameLength,_Out_opt_ DWRITE_TEXT_RANGE* textRange = NULL);

                HWIN_EXPORT WriteTextLayout& GetLocaleName(UINT32 currentPosition,_Out_writes_z_(nameSize) WCHAR* localeName,UINT32 nameSize,_Out_opt_ DWRITE_TEXT_RANGE* textRange = NULL);

                HWIN_EXPORT WriteTextLayout& Draw(_In_opt_ void* clientDrawingContext,IDWriteTextRenderer* renderer,FLOAT originX,FLOAT originY);

                HWIN_EXPORT WriteTextLayout& GetLineMetrics(DWRITE_LINE_METRICS* lineMetrics,UINT32 maxLineCount,_Out_ UINT32* actualLineCount);

                HWIN_EXPORT WriteTextLayout& GetMetrics(_Out_ DWRITE_TEXT_METRICS* textMetrics);

                HWIN_EXPORT WriteTextLayout& GetOverhangMetrics(_Out_ DWRITE_OVERHANG_METRICS* overhangs);

                HWIN_EXPORT WriteTextLayout& GetClusterMetrics(_Out_writes_opt_(maxClusterCount) DWRITE_CLUSTER_METRICS* clusterMetrics,UINT32 maxClusterCount,_Out_ UINT32* actualClusterCount);

                HWIN_EXPORT WriteTextLayout& DetermineMinWidth(_Out_ FLOAT* minWidth);

                HWIN_EXPORT WriteTextLayout& HitTestPoint(FLOAT pointX,FLOAT pointY,_Out_ BOOL* isTrailingHit,_Out_ BOOL* isInside,_Out_ DWRITE_HIT_TEST_METRICS* hitTestMetrics);

                HWIN_EXPORT WriteTextLayout& HitTestTextPosition(UINT32 textPosition,BOOL isTrailingHit,_Out_ FLOAT* pointX,_Out_ FLOAT* pointY,_Out_ DWRITE_HIT_TEST_METRICS* hitTestMetrics);

                HWIN_EXPORT WriteTextLayout& HitTestTextRange(UINT32 textPosition,UINT32 textLength,FLOAT originX,FLOAT originY,DWRITE_HIT_TEST_METRICS* hitTestMetrics,UINT32 maxHitTestMetricsCount,_Out_ UINT32* actualHitTestMetricsCount);
            };


            class WriteBitmapRenderTarget : public Unknown
            {
            public:
                typedef Unknown Base;

                HARLINN_WINDOWS_GRAPHICS_STANDARD_METHODS_IMPL(WriteBitmapRenderTarget,Unknown,IDWriteBitmapRenderTarget,IUnknown)

                HWIN_EXPORT WriteBitmapRenderTarget& DrawGlyphRun(FLOAT baselineOriginX,FLOAT baselineOriginY,DWRITE_MEASURING_MODE measuringMode,_In_ DWRITE_GLYPH_RUN const* glyphRun,IDWriteRenderingParams* renderingParams,COLORREF textColor,_Out_opt_ RECT* blackBoxRect = NULL);

                HWIN_EXPORT HDC GetMemoryDC();

                HWIN_EXPORT FLOAT GetPixelsPerDip();

                HWIN_EXPORT WriteBitmapRenderTarget& SetPixelsPerDip(FLOAT pixelsPerDip);

                HWIN_EXPORT WriteBitmapRenderTarget& GetCurrentTransform(_Out_ DWRITE_MATRIX* transform);

                HWIN_EXPORT WriteBitmapRenderTarget& SetCurrentTransform(_In_opt_ DWRITE_MATRIX const* transform);

                HWIN_EXPORT WriteBitmapRenderTarget& GetSize(_Out_ SIZE* size);

                HWIN_EXPORT WriteBitmapRenderTarget& Resize(UINT32 width,UINT32 height);
            };


            class WriteGdiInterop : public Unknown
            {
            public:
                typedef Unknown Base;

                HARLINN_WINDOWS_GRAPHICS_STANDARD_METHODS_IMPL(WriteGdiInterop,Unknown,IDWriteGdiInterop,IUnknown)

                HWIN_EXPORT WriteGdiInterop& CreateFontFromLOGFONT(_In_ LOGFONTW const* logFont,_Out_ IDWriteFont** font);

                HWIN_EXPORT WriteGdiInterop& ConvertFontToLOGFONT(IDWriteFont* font,_Out_ LOGFONTW* logFont,_Out_ BOOL* isSystemFont);

                HWIN_EXPORT WriteGdiInterop& ConvertFontFaceToLOGFONT(IDWriteFontFace* font,_Out_ LOGFONTW* logFont);

                HWIN_EXPORT WriteGdiInterop& CreateFontFaceFromHdc(HDC hdc,_Out_ IDWriteFontFace** fontFace);

                HWIN_EXPORT WriteGdiInterop& CreateBitmapRenderTarget(_In_opt_ HDC hdc,UINT32 width,UINT32 height,_Out_ IDWriteBitmapRenderTarget** renderTarget);
            };


            class WriteGlyphRunAnalysis : public Unknown
            {
            public:
                typedef Unknown Base;

                HARLINN_WINDOWS_GRAPHICS_STANDARD_METHODS_IMPL(WriteGlyphRunAnalysis,Unknown,IDWriteGlyphRunAnalysis,IUnknown)

                HWIN_EXPORT WriteGlyphRunAnalysis& GetAlphaTextureBounds(DWRITE_TEXTURE_TYPE textureType,_Out_ RECT* textureBounds);

                HWIN_EXPORT WriteGlyphRunAnalysis& CreateAlphaTexture(DWRITE_TEXTURE_TYPE textureType,_In_ RECT const* textureBounds,BYTE* alphaValues, UINT32 bufferSize);

                HWIN_EXPORT WriteGlyphRunAnalysis& GetAlphaBlendParams(IDWriteRenderingParams* renderingParams,_Out_ FLOAT* blendGamma,_Out_ FLOAT* blendEnhancedContrast,_Out_ FLOAT* blendClearTypeLevel);
            };


            class WriteFactory : public Unknown
            {
            public:
                typedef Unknown Base;

                HARLINN_WINDOWS_GRAPHICS_STANDARD_METHODS_IMPL(WriteFactory,Unknown,IDWriteFactory,IUnknown)

                HWIN_EXPORT WriteFactory(DWRITE_FACTORY_TYPE factoryType);
                    
                HWIN_EXPORT WriteFactory& GetSystemFontCollection(_Out_ IDWriteFontCollection** fontCollection, BOOL checkForUpdates = FALSE);
                HWIN_EXPORT WriteFontCollection GetSystemFontCollection(bool checkForUpdates = false);

                HWIN_EXPORT WriteFactory& CreateCustomFontCollection( IDWriteFontCollectionLoader* collectionLoader, void const* collectionKey, UINT32 collectionKeySize, _Out_ IDWriteFontCollection** fontCollection);
                HWIN_EXPORT WriteFontCollection CreateCustomFontCollection( IDWriteFontCollectionLoader* collectionLoader, void const* collectionKey, UINT32 collectionKeySize);

                HWIN_EXPORT WriteFactory& RegisterFontCollectionLoader( IDWriteFontCollectionLoader* fontCollectionLoader);
                HWIN_EXPORT WriteFactory& UnregisterFontCollectionLoader(IDWriteFontCollectionLoader* fontCollectionLoader);

                HWIN_EXPORT WriteFactory& CreateFontFileReference(_In_z_ WCHAR const* filePath,_In_opt_ FILETIME const* lastWriteTime,_Out_ IDWriteFontFile** fontFile);
                HWIN_EXPORT WriteFontFile CreateFontFileReference(_In_z_ WCHAR const* filePath,_In_opt_ FILETIME const* lastWriteTime = nullptr);

                HWIN_EXPORT WriteFactory& CreateCustomFontFileReference(void const* fontFileReferenceKey, UINT32 fontFileReferenceKeySize, IDWriteFontFileLoader* fontFileLoader, _Out_ IDWriteFontFile** fontFile);
                HWIN_EXPORT WriteFontFile CreateCustomFontFileReference(void const* fontFileReferenceKey, UINT32 fontFileReferenceKeySize, IDWriteFontFileLoader* fontFileLoader);

                HWIN_EXPORT WriteFactory& CreateFontFace(DWRITE_FONT_FACE_TYPE fontFaceType,UINT32 numberOfFiles, IDWriteFontFile* const* fontFiles, UINT32 faceIndex, DWRITE_FONT_SIMULATIONS fontFaceSimulationFlags,_Out_ IDWriteFontFace** fontFace);
                HWIN_EXPORT WriteFontFace CreateFontFace(DWRITE_FONT_FACE_TYPE fontFaceType,UINT32 numberOfFiles, IDWriteFontFile* const* fontFiles, UINT32 faceIndex, DWRITE_FONT_SIMULATIONS fontFaceSimulationFlags);

                HWIN_EXPORT WriteFactory& CreateRenderingParams(_Out_ IDWriteRenderingParams** renderingParams);
                HWIN_EXPORT WriteRenderingParams CreateRenderingParams( );

                HWIN_EXPORT WriteFactory& CreateMonitorRenderingParams(HMONITOR monitor,_Out_ IDWriteRenderingParams** renderingParams);
                HWIN_EXPORT WriteRenderingParams CreateMonitorRenderingParams(HMONITOR monitor);

                HWIN_EXPORT WriteFactory& CreateCustomRenderingParams(FLOAT gamma,FLOAT enhancedContrast,FLOAT clearTypeLevel,DWRITE_PIXEL_GEOMETRY pixelGeometry,DWRITE_RENDERING_MODE renderingMode,_Out_ IDWriteRenderingParams** renderingParams);
                HWIN_EXPORT WriteRenderingParams CreateCustomRenderingParams(FLOAT gamma,FLOAT enhancedContrast,FLOAT clearTypeLevel,DWRITE_PIXEL_GEOMETRY pixelGeometry,DWRITE_RENDERING_MODE renderingMode);

                HWIN_EXPORT WriteFactory& RegisterFontFileLoader(IDWriteFontFileLoader* fontFileLoader);
                HWIN_EXPORT WriteFactory& UnregisterFontFileLoader(IDWriteFontFileLoader* fontFileLoader);

                HWIN_EXPORT WriteFactory& CreateTextFormat(_In_z_ WCHAR const* fontFamilyName, _In_opt_ IDWriteFontCollection* fontCollection, DWRITE_FONT_WEIGHT fontWeight, DWRITE_FONT_STYLE fontStyle, DWRITE_FONT_STRETCH fontStretch, FLOAT fontSize,_In_z_ WCHAR const* localeName,_Out_ IDWriteTextFormat** textFormat);
                HWIN_EXPORT WriteTextFormat CreateTextFormat(_In_z_ WCHAR const* fontFamilyName, _In_opt_ IDWriteFontCollection* fontCollection, DWRITE_FONT_WEIGHT fontWeight, DWRITE_FONT_STYLE fontStyle, DWRITE_FONT_STRETCH fontStretch, FLOAT fontSize,_In_z_ WCHAR const* localeName);
                HWIN_EXPORT WriteTextFormat CreateTextFormat(_In_z_ WCHAR const* fontFamilyName, FLOAT fontSize);

                HWIN_EXPORT WriteFactory& CreateTypography(_Out_ IDWriteTypography** typography);
                HWIN_EXPORT WriteTypography CreateTypography();

                HWIN_EXPORT WriteFactory& GetGdiInterop(_Out_ IDWriteGdiInterop** gdiInterop);
                HWIN_EXPORT WriteGdiInterop GetGdiInterop();

                HWIN_EXPORT WriteFactory& CreateTextLayout(WCHAR const* string, UINT32 stringLength, IDWriteTextFormat* textFormat,FLOAT maxWidth, FLOAT maxHeight,_Out_ IDWriteTextLayout** textLayout);
                HWIN_EXPORT WriteTextLayout CreateTextLayout(WCHAR const* string, UINT32 stringLength, IDWriteTextFormat* textFormat,FLOAT maxWidth, FLOAT maxHeight);

                HWIN_EXPORT WriteFactory& CreateGdiCompatibleTextLayout(WCHAR const* string, UINT32 stringLength, IDWriteTextFormat* textFormat, FLOAT layoutWidth, FLOAT layoutHeight, FLOAT pixelsPerDip,_In_opt_ DWRITE_MATRIX const* transform, BOOL useGdiNatural, _Out_ IDWriteTextLayout** textLayout);
                HWIN_EXPORT WriteTextLayout CreateGdiCompatibleTextLayout(WCHAR const* string, UINT32 stringLength, IDWriteTextFormat* textFormat, FLOAT layoutWidth, FLOAT layoutHeight, FLOAT pixelsPerDip,_In_opt_ DWRITE_MATRIX const* transform, BOOL useGdiNatural);

                HWIN_EXPORT WriteFactory& CreateEllipsisTrimmingSign( IDWriteTextFormat* textFormat,_Out_ IDWriteInlineObject** trimmingSign);
                HWIN_EXPORT WriteInlineObject CreateEllipsisTrimmingSign( IDWriteTextFormat* textFormat);

                HWIN_EXPORT WriteFactory& CreateTextAnalyzer(_Out_ IDWriteTextAnalyzer** textAnalyzer);
                HWIN_EXPORT WriteTextAnalyzer CreateTextAnalyzer( );

                HWIN_EXPORT WriteFactory& CreateNumberSubstitution(_In_ DWRITE_NUMBER_SUBSTITUTION_METHOD substitutionMethod, _In_z_ WCHAR const* localeName, _In_ BOOL ignoreUserOverride, _Out_ IDWriteNumberSubstitution** numberSubstitution);

                HWIN_EXPORT WriteFactory& CreateGlyphRunAnalysis(_In_ DWRITE_GLYPH_RUN const* glyphRun,FLOAT pixelsPerDip,_In_opt_ DWRITE_MATRIX const* transform, DWRITE_RENDERING_MODE renderingMode, DWRITE_MEASURING_MODE measuringMode, FLOAT baselineOriginX, FLOAT baselineOriginY, _Out_ IDWriteGlyphRunAnalysis** glyphRunAnalysis);
                HWIN_EXPORT WriteGlyphRunAnalysis CreateGlyphRunAnalysis(_In_ DWRITE_GLYPH_RUN const* glyphRun,FLOAT pixelsPerDip,_In_opt_ DWRITE_MATRIX const* transform, DWRITE_RENDERING_MODE renderingMode, DWRITE_MEASURING_MODE measuringMode, FLOAT baselineOriginX, FLOAT baselineOriginY);

            };


        };
    };
};

#endif //__HWINGRAPHICS_H__
